我们几天前就遇到了这个问题 . 那时,我们将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_datepicker ( dojox.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')