Developing an AngularJS app with dynamic set of modules

后端 未结 2 608
盖世英雄少女心
盖世英雄少女心 2020-12-12 08:27

I have an application with a complex layout where the user could put (drag/drop) widgets (by choosing from a predefined set of 100+ widgets) where every widget is a custom i

2条回答
  •  悲哀的现实
    2020-12-12 09:12

    This question is also very important to me. The AngularJS homepage has a few examples on it (you could call them widgets) so I went though their source code to try and see how they separated their widgets.

    First, they never declare an "ng-app" attribute. They use

    function bootstrap() {
          if (window.prettyPrint && window.$ && $.fn.popover && angular.bootstrap &&
              hasModule('ngLocal.sk') && hasModule('ngLocal.us') && hasModule('homepage') && hasModule('ngResource')) {
                $(function(){
                  angular.bootstrap(document, ['homepage', 'ngLocal.us']);
                });
          }
        }
    

    to make sure everything is loaded correctly. Neat idea, but it's odd that they push the ng-app attribute on you so much then don't even use it themselves. Anyways here is the homepage module they load with the app - http://angularjs.org/js/homepage.js

    In there is a directive called appRun

      .directive('appRun', function(fetchCode, $templateCache, $browser) {
        return {
          terminal: true,
          link: function(scope, element, attrs) {
            var modules = [];
    
            modules.push(function($provide, $locationProvider) {
              $provide.value('$templateCache', {
                get: function(key) {
                  var value = $templateCache.get(key);
                  if (value) {
                    value = value.replace(/\#\//mg, '/');
                  }
                  return value;
                }
              });
              $provide.value('$anchorScroll', angular.noop);
              $provide.value('$browser', $browser);
              $locationProvider.html5Mode(true);
              $locationProvider.hashPrefix('!');
            });
            if (attrs.module) {
              modules.push(attrs.module);
            }
    
            element.html(fetchCode(attrs.appRun));
            element.bind('click', function(event) {
              if (event.target.attributes.getNamedItem('ng-click')) {
                event.preventDefault();
              }
            });
            angular.bootstrap(element, modules);
          }
        };
      })
    

    I'll use the ToDo list as an example. For the html, they have

    and then at the bottom of the page they have

    
    

    They also have

    
    
    

    The code is used, but the id attributes on those scripts aren't important for running the app. That's just for the source code display to the left of the app.

    Basically, they have a directive called appRun which uses a function fetchCode

      .factory('fetchCode', function(indent) {
        return function get(id, spaces) {
          return indent(angular.element(document.getElementById(id)).html(), spaces);
        }
      })
    

    to fetch the code. Then they use angular.bootstrap() to create a new application. They can also load modules though app-run. The JavaScript Project example is initialized like

    Hopefully this helps. I'm still not sure what's the "best" technique, but it appears as though the AngularJS homepage simply uses a totally separate angular application (ng-app) for each example/widget. I think I'm going to do the same, except change the fetchCode function to get stuff with AJAX.

提交回复
热议问题