仅在定义$scope.myVar后呈现AngularJS指令

仅在定义$scope.myVar后呈现AngularJS指令,angularjs,angularjs-directive,angularjs-scope,Angularjs,Angularjs Directive,Angularjs Scope,加载AngularJS“页面”时,我从服务器获取一些数据并将其设置为作用域: myApp.controller('somePage', ['$scope', 'User', '$routeParams', function($scope, User, $routeParams){ // Get the user. User.get('1234').then(function(user){ $scope.user = user; }); }); 在我的页面上,我有一个指令

加载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>'
  };
})
myApp.directive('addActionButton',function(){
返回{
范围:假,
链接:函数(范围、元素、属性){
元素绑定('单击',函数(){
警报(scope.user.name);
});
},
模板:“向{{user.name}问好”
};
})
现在,页面在定义
$scope.user
之前呈现组件,因此存在错误

如何使此指令仅在
$scope.user
存在时呈现?
或者如何使页面视图仅在控制器获取其数据后呈现


编辑:上面的所有代码都大大简化了,因此您不必阅读额外的信息,但仍然有组件所需的约束(例如链接、带属性的模板、带ajax调用的范围)。

我认为您更担心的是指令内部的处理太早,而不是指令的呈现。您可以设置双向绑定并附加承诺,或者可以使用事件通知指令启动,或者可以在初始化指令过程之前对数据设置一次性监视。所以,基本思想不是直接在指令链接函数中编写处理代码。另外,一个好主意是让控制器与指令关联,并在获得数据后触发指令控制器中的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>


如果您担心根本无法呈现指令,只需在指令元素上使用
ng if
,只要您的指令优先级小于ng if它就不会呈现。

用于此:

<user-profile-info ng-if="user"></user-profile-info>

请参见此示例:


angular.module('myApp',[])
.controller('somePage',['$scope','$timeout',函数($scope,$timeout){
//获取用户
//模拟延迟请求,3秒
$timeout(函数(){
$scope.user={
名称:“Shomz”
};
}, 3000);
}])
.directive('userProfileInfo',function(){
返回{
限制:'E',
链接:函数(范围、元素、属性){
元素绑定('单击',函数(){
警报(scope.user.name);
});
警报(scope.user.name);//如果
},
模板:“向{{user.name}问好”
};
})

正在等待用户数据

qwe
在scope.user上添加watch并查看newvalues,但如果需要5秒钟才能获取scope.user值,则组件在准备就绪之前仍将被损坏。为此,请使用ng show隐藏无效value@DonnyP你能展示你的指令代码吗@更进一步,即使使用包装
ng show
元素,Angular仍将编译并链接该指令;因此,如果指令以前抛出异常,它仍然会抛出异常。但这是一个正确的想法,一个
ng if
条件为
user!==未定义的
应该可以做到这一点,因为
ng if
将显式停止编译任何嵌套指令。我认为您更担心的是处理而不是呈现。您可以设置双向绑定并附加承诺,或者可以使用事件通知指令启动,或者可以在初始化指令过程之前对数据设置一次性监视。您的指令看起来如何?@Shornz-如果我想让ng if等待多个模型,例如“user”和“question”,我该怎么做
ng if=“user&&question”
似乎合理,但这是正确的吗?谢谢,这很有效:)在接受之前,让我先看看PSL的答案,不客气!没问题,@PSL的回答很棒。@DonnyP我想这可能是一个准确的答案,用于这个指令的确切目的,在编辑问题以包括指令之前,我用所有选项写下了我的答案:)。这可能是一个问题,这个指令应该如何自我约束?如果需要,用户是否应该担心放置ng,或者指令是否可以自行处理_肖姆兹我从来没有意识到。。谢谢:)是的,这里的问题就像@PSL指出的关于自我包容的问题。尽管如此,我还是在我的用例中使用了这个解决方案,并确保对其进行评论。手表、事件等往往会添加一些额外的代码和膨胀。老实说,我对这两种解决方案都不满意。我希望他能为我们处理好这件事,我想这会和生活挂钩事件有关。可悲的是,旧版本:(
 <user-profile-info user="userPromise"></user-profile-info>
<user-profile-info ng-if="user"></user-profile-info>