angularjs指令在链接函数中使用参数

时间:2015-08-31 11:24:06

标签: javascript angularjs angularjs-directive

这可能是一个愚蠢的问题,但我已经坚持了几天,而且谷歌搜索解决方案都没有为我辩护。

我正在按照指令驱动方法编写一个角度1.4应用程序,因此对于任何实体我都有一个或多个小部件:

  • 隔离范围
  • controller as
  • bindToController true

问题在于“用户有东西”的种类。

<user-widget>
   <stuff-widget userid="user._id"></stuff-widget>
</user-widget>

userid很好地传递到widget中,但是我想在stuff widget的链接函数中使用它,因为东西真的很复杂,而且在现实世界里我也需要抓住其他各个部分。

我尝试了各种方法来获取userid值(如各种其他stackoverflow讨论和网络上其他地方所建议的那样)

  • 使用bidrectional binding - &gt;没有效果
  • 通过范围和控制器尝试 - &gt; userid,uid未定义
  • require ^ userWidget - &gt;失去了对我的控制器的访问权
  • 使用attrs。$ observe('userid',....) - &gt; js错误:未定义用户标识
  • 通过父母的前链接传递 - &gt;确实有效,但不是一个好主意/有限的优点

我有一个关于我尝试的各种事情的人:http://plnkr.co/edit/SqlhYSteCDxMaAVZWCsy?p=info

小部件看起来像这样(工作前链接变体)

  function userWidget() {
    return {
      restrict: 'EA',
      scope:{},
      template: '<h2>User</h2> {{user.name}}<stuff-widget userid="user._id"></stuff-widget>',
      replace: false,
      controllerAs: 'userCtrl',
      bindToController: true,
      controller: 'UserCtrl',
      link: { // this actually works, not sure wether this a good idea
        pre: function preLink(scope, element, attrs, ctrl) {
          var uid = 1;
          scope.user = ctrl.findById(uid);
          scope.userid = scope.user._id;
    },
    post: function postLink(scope, element, attrs, ctrl) {}
      }

    };
  }

  function stuffWidget() {
    return {
      restrict: 'EA',
      scope: {
        uid: '=userid'
      }, 
      template: '<h3>User stuff</h3>stuffCtrl.userid inside widget: {{stuffCtrl.userid}}<div ng-repeat="stuff in stuffCtrl.userStuff">\
User id: {{stuff.userid}}: {{stuff.stuff}}\
</div>',
      replace: false,
      controller: 'StuffCtrl',
      controllerAs: 'stuffCtrl',
      bindToController: {
        userid: '='
      },
      link: function (scope, element, attrs, ctrl) {
    console.log('stuff ctrl userid:', ctrl.userid); // not defined
    console.log('stuff scope uid:', scope.uid); // not defined
    console.log('Scope parent userid: ',scope.$parent.userid); // undefined

    // didn't work either - userid not defined
    /* attrs.$observe('userid', function(value) {
      if (value) {
        ctrl.userid = userid;
        console.log('stuff ctrl userid observed:', ctrl.userid);
      }
    }); */
    ctrl.userStuff = ctrl.findByUserId(ctrl.userid);
      }
    };
  } 

我是一个有角度的初学者(第一个严肃的项目),到目前为止,我的经验是:“如果很难弄清楚,你可能会以错误的方式做到这一点。”

所以,

  • 我是否错过了在链接功能中访问参数的明显方法?
  • 我是否搞砸了我尝试过的方式(特别是$ observe),因为我错误地将它们转移到了我的设置?
  • 我应该将控制器调用粘贴在模板中并完成吗?
  • 我应该以完全不同的方式解决这个问题吗?编译功能?控制器功能?还有其他我不熟悉的角度深度?

2 个答案:

答案 0 :(得分:0)

链接功能完成执行后,您必须等待一个摘要周期,以便从使用该指令的范围更新隔离范围内的值。

您可以在 stuffWidged

中试用此代码段
link: function(scope, element, attrs, ctrl) {
  var uid, usrStuff;

  scope.uid; // it is normal to be undefined here

  scope.$watch('uid', function(newUid) {
    uid = newUid;

    scope.uid; // is ready and is same as newUid

    usrStuff = ctrl.usrStuff = scope.usrStuff =
      ctrl.findById(uid);
  });
}

答案 1 :(得分:0)

  1. 从用户窗口小部件中删除隔离范围 - 你真的需要吗?如果您没有在指令范围内定义任何其他变量 - 您实际上并不需要隔离范围。
  2. 隔离范围。那么user-widget应该有一些参数?像:
  3. <user-widget widgetusers="model.users"></user-widget>
    

    然后用户窗口小部件模板将是:

    <stuff-widget ng-repeat="stuffuser in widgetusers" userid="stuffuser._id"></stuff-widget>
    
    1. 您可以先将userId传递给userWidget,然后传递给stuffWidget:
    2. <user-widget userid="user._id">
         <stuff-widget userid="userid"></stuff-widget>
      </user-widget>