我们几天前就遇到了这个问题 . 那时,我们将Angular引入基于HTML5的移动家庭照片社交应用Family Snap . 它由www.uhella.com维护 .

在重组期间,我将dojo代码移动到指令内联,它运行良好 . calendar_month_datepicker (dojox.mobile.SpinWheelDatePicker) 被dijit成功注入了一个巨大的Div然后 .

之后,我想将它分成单独的html文件作为模板,因为html编辑器将更好地理解我的html代码 . 所以我修改代码如下:

Familysnap /指令/ homepickdata.js

'use strict';
/* Directives */
FamilySnapModule.directive('homePickdata', function() {
    return  {
        restrict: 'EAC',
        replace: true,
        transclude: true,
        templateUrl: 'Familysnap/templates/homePickdata.html'
        //template: '<div id="calendar_month_datepicker" data-dojo-type="dojox.mobile.SpinWheelDatePicker" data-dojo-props=\'slotOrder: [0,1,2], monthPattern: "MM", dayPattern: "dd", align: "center"\'></div>'
        };
});

Familysnap /模板/ homePickdata.html

<div id="calendar_month_datepicker" data-dojo-type="dojox.mobile.SpinWheelDatePicker" data-dojo-props='slotOrder: [0,1,2], monthPattern: "MM", dayPattern: "dd", align: "center"'></div>

Familysnap /模块/ dataPicker.js

require([
    …
             ], function(dom, domStyle, domAttr, on, ready, registry, JSON, string,
                         ListItem, array, request, domClass, query, domProp, domConstruct, tap, swipe, Uuid, generateRandomUuid,
                         Pane, SpinWheelDatePicker, win, Opener, Heading, ToolBarButton, SwapView) {        


    function FamilySnapMonthToday()
    {
        …

        setTimeout(function(){

        registry.byId("calendar_month_datepicker").set("values", [global_calendar_current_year, global_calendar_current_month + 1, global_calendar_current_date]);
    }, 500);
    …
}

function FamilySnapMonthDone()
{…

    var values = registry.byId("calendar_month_datepicker").get("values");
 …
}

ready(function(){
…
        on(dom.byId("calendar_month_done_btn"), "click", FamilySnapMonthDone);
    …
    });
});

在此修改之后, calendar_month_datepickerdojox.mobile.SpinWheelDatePicker )未被dijit注入 . 它只是由角度编译器注入 . 并且“ registry.byId("calendar_month_datepicker") ”将始终返回null .

我终于弄清楚模板和templateUrl之间的加载顺序在角度编译器中是由chrome源代码调试工具(Debugging-in-PhoneGap)不同的 .

首先,我在我的指令上设置了断点 .

当时代码暂停了我的断点 .

Familysnap /指令/ homepickdata.js

'use strict';
/* Directives */
FamilySnapModule.directive('homePickdata', function() {

return {

restrict: 'EAC',
            replace: true,
            transclude: true,
            templateUrl: 'angular/templates/homePickdata.html'
            //template: '<div id="calendar_month_datepicker" data-dojo-type="dojox.mobile.SpinWheelDatePicker" data-dojo-props=\'slotOrder: [0,1,2], monthPattern: "MM", dayPattern: "dd", align: "center"\'></div>'
            };
    });

两个版本中的指令“home-pickdata”未注入 . 这是我们的期望 .

<div home-pickdata></div>

不同之处在于:

function bootstrap(element, modules) {
  var doBootstrap = function() {
    element = jqLite(element);

    if (element.injector()) {
      var tag = (element[0] === document) ? 'document' : startingTag(element);
      throw ngMinErr('btstrpd', "App Already Bootstrapped with this Element '{0}'", tag);
    }

    modules = modules || [];
    modules.unshift(['$provide', function($provide) {
      $provide.value('$rootElement', element);
    }]);
    modules.unshift('ng');
    var injector = createInjector(modules);
    injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector', '$animate',
       function(scope, element, compile, injector, animate) {
        scope.$apply(function() {
          element.data('$injector', injector);

compile(element)(scope);

});
      }]
    );
    return injector;
  };

在compile(element)(范围)之后,指令的模板版本注入如下:

<div id="calendar_month_datepicker" data-dojo-type="dojox.mobile.SpinWheelDatePicker" data-dojo-props='slotOrder: [0,1,2], monthPattern: "MM", dayPattern: "dd", align: "center"'></div>

但是templateUrl版本仍然是:

<div home-pickdata></div>

即使在angularInit之后:

//try to bind to jquery now so that one can write angular.element().read()
  //but we will rebind on bootstrap again.
  bindJQuery();

  publishExternalAPI(angular);

  jqLite(document).ready(function() {
    angularInit(document, bootstrap);
  });

})(window, document);

templateUrl版本仍然是:

<div home-pickdata></div>

在此钩子之后,dojo注入器将处理所有dojo标记,但此时,Angular仍未注入templateUrl版本的指令 .

所以dojo / dijit不知道ID“ calendar_month_datepicker ” . 这解释了为什么registry.byId(“calendar_month_datepicker”)在我们的代码中返回NULL .

我不熟悉dojo注入器 . 我相信有办法通过一些魔法使dojo与angular templateUrl指令一起工作 .

通过阅读Dimitri M和tik27的答案,我更新了代码 . 我们需要手动调用“dojo / parser”来注入我们的小部件 .

将data_ dojo -type更改为data- familysnap -type .

<div id="calendar_month_datepicker" data-family-type="dojox.mobile.SpinWheelDatePicker" data-dojo-props='slotOrder: [0,1,2], monthPattern: "MM", dayPattern: "dd", align: "center"'></div>

并在ready()上调用解析器

require(["dojo/parser"],function(dom,registry,parser)){

        ready() {
    parser.parse({scope: "familysnap"});
    ...
        }
}

然后dijit注入了calendar_month_datepicker . 我们可以成功打电话

registy.byId('calendar_month_datepicker')