gpt4 book ai didi

javascript - 指令在其子项之前初始化

转载 作者:行者123 更新时间:2023-11-30 12:22:22 24 4
gpt4 key购买 nike

我有 2 个指令,一个负责主元素 <swapview>另一个给它的 child <view> .然而,在加载子模板时 var views = $('view', elem);已经执行并找到 0 <view> DOM 中的元素。

我只是缺乏关于这个问题的经验任何想法都会非常有帮助

  1. 如何解决异步问题?
  2. 我不确定这种可靠指令模式是否正确。我将不胜感激关于这方面的任何提示或我可以检查的良好实践资源。

HTML:

<swapview>
<view ng-repeat="view in views" templateurl="{{::view.template}}"></view>
</swapview>

js

  App.directive('view', function () {
return {
scope:{
templateurl: '@'
},
controller: function($scope) {
$scope.getTemplateUrl = function () {
return $scope.templateurl;
};
},
template: '<ng-include src="getTemplateUrl()"/>'
};
});


App.directive('swapview', ['$swipe',function ($swipe) {
//....

return {
link: function (scope, elem, attrs) {

var views = $('view', elem);
var count = views.length;

//......
},
require: 'view'
};
}]);


var ctrls = ang.module('controllers',[]);

ctrls.controller('myController', ['$scope', function ($scope) {
$scope.views = [
{template:'templates/viewI.html'},
{template:'templates/viewII.html'},
{template:'templates/viewIII.html'},
{template:'templates/viewIV.html'}
];
}]);

感谢您的帮助

最佳答案

link 阶段依赖子 DOM 元素是一种非常脆弱的方法。

当元素已经存在时它会起作用:

<swapview>
<view templateUrl="view1.html"></view>
<view templateUrl="view2.html"></view>
</swapview>

但是如果你有 ng-ifng-repeat将无法工作,因为这两个指令将自身嵌入并且只评估是否“稍后”呈现自己,因此在 link 中您会看到一个占位符注释(即使 `ng-if="true"):

<swapview>
<view ng-if="true" templateUrl="view1.html">
</swapview>

可以通过(hackish)$timeout 方法克服这个问题 - 它不会导致竞争条件 - 这不是 hackish - 实际上每次都有效(即使延迟为 0),因为 $timeout 将执行置于摘要周期的末尾:

console.log(element.find("view").length); // will output 0
$timeout(function(){
console.log(element.find("view").length); // will output 1
});

不过,这不是一个好的解决方案。如果您的指令的用户决定动态加载内容,例如使用 ng-include,这将中断。因此,如果需要下载模板,即使使用 $timeout,以下也不会工作:

<swapview>
<div ng-include="'templateForViews.html`"></div>
<swapview>

那么,什么有效?

处理预期的子指令的正确方法是让子指令自己向父 Controller 注册一个带有 require: "^parent" 的 Controller :

.directive("swapview", function($timeout){
return {
controller: function(){
var childViewCtrls = [];

this.registerView = function(view, viewEl){
childViewCtrls.push({ctrl: view, elem: viewEl});
};
},
link: function(scope, element){
//
}
};
})

.directive("view", function($timeout){
return {
require: ["view", "^swapview"],
controller: function(){
// useful to expose an API
},
link: function(scope, element, attrs, ctrls){
var me = ctrls[0],
swapview = ctrls[1];

swapview.registerView(me, element);
}
};
});

关于javascript - 指令在其子项之前初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30585039/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com