Custom指令的范围模型未定义

时间:2016-06-13 01:31:38

标签: javascript angularjs angularjs-directive ionic-framework

背景:我有一个Ionic应用程序,它使用collection-repeat显示联系人列表(对Angular ng-repeat的离子改进)。顶部有两个切换按钮,用于决定显示哪个联系人列表。我写了一个自定义指令来显示联系人的图片,标题和副标题。

HTML

  <ion-content>
    <ion-list>
      <div class="item item-avatar" collection-repeat="contact in viewing" force-refresh-images="true">
        <profile-or-initials ng-model="contact"></profile-or-initials>
        <h2>{{contact.title}}</h2>
        <p>{{contact.subtitle}}</p>
      </div>
    </ion-list>
  </ion-content>

JS

var app = angular.module('myApp', ['ionic']);
app.directive('profileOrInitials', function($state) {
    return {
      restrict: "E",
      scope: {
        ngModel: '='
      },
      replace: true,
      template: '<div class="profileOrInitials"></div>',
      link: function(scope, element) {
        var getInitials = function(user) {
          return user.title.substring(0, 2);

        };
        var process = function() {
          var image = scope.ngModel.feed_pic_url;
          var initials = getInitials(scope.ngModel);
          var html = '';

          if (image) {
            html = '<img src="' + image + '"></img>';
          } else {
            image = "http://science-all.com/images/wallpapers/blue-image/blue-image-14.jpg";
            html = '<img src="' + image + '"></img><div class="initials">' + initials + '</div>';
          }

          element.html(html);
        };
        //var destroy = scope.$watch('ngModel', function() {
        //  if (scope.ngModel) {
             process();
            //destroy();
          //}
        //});
      }
    };
  })

问题:指令的ngModel范围为undefined,除非我为其添加scope.$watch函数。更进一步,如果我在该表上调用destroy函数,该指令也会停止工作,因为当您单击按钮时,图片不会更新。

此处是Plunker:http://plnkr.co/edit/t4opQdqr4VStpqP6MdQn

任何人都可以解释这里发生了什么吗?我不关心实际的解决方案。我只是不明白发生了什么。我的怀疑是我的指令的link函数在collection-repeat之前运行,因此在那时模型是未定义的,但我尝试降低它的优先级,但它仍然不起作用。 (collection-repeat has a priority of 1000)。

1 个答案:

答案 0 :(得分:0)

这基本上是因为collection-repeat的工作原理。它将在渲染之前为集合创建占位符。如果您尝试使用ng-repeat,您会发现它工作正常。

作为使用collection-repeat的补救措施/解决方案,您可以考虑使用以下内容:

.directive('profileOrInitials', function($state) {
    return {
      restrict: "E",
      require: 'ngModel',
      replace: true,
      template: '<div class="profileOrInitials"></div>',
      link: function(scope, element, attrs, model) {
        var getInitials = function(user) {
          return user.title.substring(0, 2);
        };
        model.$render = function() {
          m = model.$viewValue;
          var image = m.feed_pic_url;
          var initials = getInitials(m);
          var html = '';

          if (image) {
            html = '<img src="' + image + '"></img>';
          } else {
            image = "http://science-all.com/images/wallpapers/blue-image/blue-image-14.jpg";
            html = '<img src="' + image + '"></img><div class="initials">' + initials + '</div>';
          }

          element.html(html);
        }
      }
    };
});

请注意,我使用了require: 'ngModel',以便模型作为第4个参数传递给link函数。无需明确声明范围。

最后,当您第一次设置模型时,将自动调用model.$render,即单击示例顶部的任何按钮时。

可以使用model.$viewValue

检索模型的值