当我的AngularJS"页面"加载,我从服务器获取一些数据并将其设置为范围:
myApp.controller('somePage', ['$scope', 'User', '$routeParams', function($scope, User, $routeParams){
// Get the user.
User.get('1234').then(function(user){
$scope.user = user;
});
});
在我的页面上,我有一个需要定义$scope.user
的指令。
<div>
<user-profile-info></user-profile-info>
</div>
指令:
myApp.directive('addActionButton', function() {
return {
scope: false,
link: function(scope, element, attrs){
element.bind('click', function(){
alert(scope.user.name);
});
},
template: '<button id="foo">Say hi to {{ user.name }}</button>'
};
})
现在,页面在定义$scope.user
之前呈现组件,因此存在错误。
如何在$scope.user
存在时才能使此指令生效?或者,一旦控制器获取数据后,如何才能使我的页面视图呈现?
答案 0 :(得分:8)
ng-if就是为了这个目的:
<user-profile-info ng-if="user"></user-profile-info>
见这个例子:
angular.module('myApp', [])
.controller('somePage', ['$scope', '$timeout', function($scope, $timeout){
// Get the user
// simulating delayed request, 3 secs
$timeout(function(){
$scope.user = {
name: 'Shomz'
};
}, 3000);
}])
.directive('userProfileInfo', function() {
return {
restrict: 'E',
link: function(scope, element, attrs){
element.bind('click', function(){
alert(scope.user.name);
});
alert(scope.user.name); // this would throw an error without ng-if
},
template: '<button id="foo">Say hi to {{ user.name }}</button>'
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="somePage">
<p ng-hide="user">Waiting for user data...</p>
<user-profile-info ng-if="user">qwe</user-profile-info>
</div>
答案 1 :(得分:3)
我认为你过早担心指令内部的处理而不是渲染指令。您可以设置双向绑定并附加承诺,或者您可以使用事件让指令知道启动,或者您可以在初始化指令进程之前设置对数据的一次性监视。所以基本思路不是直接在指令链接函数中编写处理代码。同样最好让控制器与指令相关联,并在获得数据后触发指令控制器中的init函数。
一个简单的例子,包括一次性和承诺方法。
.directive('userProfileInfo', function($q){
return{
/*Your configuration*/,
scope:{user:"="},
link: function linker(scope, elm, attrs){
/*
Promise way
*/
//Set up data or promise, q.when will make sure it is always a promise, be careful about not setting values like null etc..
$q.when(scope.user).then(init);
/*
One time watch way
*/
var unwatch = scope.$watch('user', function(user){
if(angular.isDefined(user)){
unwatch(); //Remove the watch
init(); //initialize
}
});
function init(){
//Initialize directive processing accessing scope.user
}
}
}
});
并将其绑定为:
<user-profile-info user="user"></user-profile-info>
如果您正在使用一次性监视,请使用保证方法保持代码不变。约束承诺,即
在您的控制器中:
$scope.userPromise = User.get('1234');
和
<user-profile-info user="userPromise"></user-profile-info>
如果您担心不能完全呈现该指令,只需在指令元素上使用ng-if
,只要您的指令优先级小于ng-ifs它就不会呈现。