Anguler JS Learning (V) On-demand Dynamic Loading of Files

Keywords: angular Attribute Programming github

Before that, I need to know a few things first.

$q

Introduction:

$q: The main problem is asynchronous programming, which describes the interaction between the results of an action executed asynchronously on behalf of an object through a commitment behavior, and may or may not be completed at any time.

We understand the $q service through a short story.

  1. Buy out at noon, call for a fried rice, request to be sent to the company and give the boss the specific address. This process is $q.defer;
  2. The meal could not be delivered immediately, so it was a request for a deferred response.
  3. The boss said it would be delivered as soon as possible. The boss gave me a promise.
  4. I can wait while I work, indicating that the request is an asynchronous execution process.
  5. This delayed asynchronous request is then established. It's a deferred.
  6. The meal was sent to me for acceptance, a process called deferred.resolve(data) response event;
  7. If the rice is sold out, the boss will tell me that I can't do it, that is, to refuse my request, that is deferred.reject(error);
  8. The boss can tell me at any time that he can't do it, as long as he hasn't delivered the meal yet.
  9. Come downstairs and tell me to pick it up. This is the notification deferred.notify(data)
    This completes the whole asynchronous callback process.
  10. The next day, many of us had to order meals. So I can launch $q.all(req1,req2,req3.);

Use

In the service, we define deferred between requests and return deferred.promise. deferred.resolve(data) when data is obtained. Similarly, we can receive notification or rejection in the middle.

var def = $q.defer();
def.resolve(data);
return def.promise;

Load on demand

First of all, we need to know a few points:

  • When to load:
    Both ngRoute and uiRoute provide values in the resolve attribute that are pre-set before routing succeeds and then injected into the controller. Popularly, it is only after the data is "in place" that routing is carried out (in fact, I don't think it can be called routing, because routing is the operation of some columns, including setting the resolve attribute and so on). You can refer to my last article.
  • How to register a loaded file:
    Angular has a starter function called bootstrap. According to angular code design, you need to define all controllers before starting. It's like having a bag. You can stuff whatever you want in it before bootstrap. But once bootstrap is gone, he will no longer accept any controllers you put in.
    There is only one way to solve this problem, which is to use the provider of the main module to actively register the controller. But because the provider can't be used directly, we store it under the main module. The saved method can be used to register asynchronously loaded page components.
  • From the above, we know that we need to load files asynchronously.

Realization

// controller
define(["app"], function(app) {
    app.config(["$stateProvider", "$urlRouterProvider", "$controllerProvider",
        function($stateProvider, $urlRouterProvider, $controllerProvider) {
            // angular has a starter function called bootstrap.
            // According to angular code design, you need to define all controller s before starting.
            // It's like having a bag. You can stuff whatever you want in it before bootstrap.
            // But once bootstrap is over, he no longer accepts any controller s you put in.
            // There is only one way to solve this problem, which is to register controller actively by using the provider of the main module.
            // But because provider can't be used directly, we put it under the main module.
            // The saved method can be used to register asynchronously loaded page components.
            app.registerController = $controllerProvider.register;
            app.loadFile = function(js) {
                return function($rootScope, $q) {
                    //Register a deferred object through the $q service
                    var def = $q.defer(),
                        deps = [];
                    angular.isArray(js) ? (deps = js) : deps.push(js);
                    require(deps, function() {
                        $rootScope.$apply(function() {
                            // Success
                            def.resolve();
                            // def.reject() was unsuccessful
                            // def.notify() update status
                        });
                    });
                    //By deferred deferred objects, a promise can be obtained, and promise returns the completion result of the current task.
                    return def.promise;
                };
            }
            $urlRouterProvider.otherwise('/index');
            $stateProvider.state("index", {
                url: "/index",
                template: "This is the home page."
            });
            $stateProvider.state("computers", {
                url: "/computers",
                template: "This is the computer classification page.{{title}}",
                controller: "ctrl.file",
                resolve: {
                    loadFile: app.loadFile("file")
                }
            });
            $stateProvider.state("printers", {
                url: "/printers",
                template: "This is the printer page."
            });
            $stateProvider.state("blabla", {
                url: "/blabla",
                template: "Other"
            });
        }
    ]);
});
// file.js
define(["app"], function(app) {
    app.registerController("ctrl.file", function($scope) {
        $scope.title = "--test ";
    });
});

Source code: https://github.com/ZangYuSong/requireLearn

Posted by NogDog on Tue, 26 Mar 2019 14:54:30 -0700