【问题标题】:Cannot read data "objectname" of undefined angular directive无法读取未定义角度指令的数据“对象名”
【发布时间】:2016-08-23 07:26:26
【问题描述】:

无法从父作用域读取数据到指令。出现类似

的错误

TypeError:无法读取未定义的属性“rowCollection”

你能帮我解决这个问题吗?

HTML

<div ng-controller="ctrl1 as one">
   <ltcg-table options="one.rowCollection"></ltcg-table>     
</div>

网格 HTML

<table st-table="rowCollection" class="table table-striped">
    <thead>
    <tr>
        <th>first name</th>
        <th>last name</th>
        <th>birth date</th>
        <th>balance</th>
        <th>email</th>
    </tr>
    </thead>
    <tbody>
    <tr ng-repeat="row in rowCollection">
        <td>{{row.firstName}}</td>
        <td>{{row.lastName}}</td>
        <td>{{row.birthDate}}</td>
        <td>{{row.balance}}</td>
        <td>{{row.email}}</td>
    </tr>
    </tbody>
</table>

Javascript 控制器

(function () {

      var myApp = angular.module('myApp', ['smart-table']);

          function one() {
                       this.song="Murali";
                      // alert("gg");
                     this.rowCollection = [
                        {firstName: 'Laurent', lastName: 'Renard', birthDate: new Date('1987-05-21'), balance: 102, email: 'whatever@gmail.com'},
                        {firstName: 'Blandine', lastName: 'Faivre', birthDate: new Date('1987-04-25'), balance: -2323.22, email: 'oufblandou@gmail.com'},
                        {firstName: 'Francoise', lastName: 'Frere', birthDate: new Date('1955-08-27'), balance: 42343, email: 'raymondef@gmail.com'}
                    ];
                      //alert($scope.gridOptions.columnDefs[1].name);
                       //alert($scope.gridOptions);
             };




        myApp.directive('ltcgTable', function() {

            return {
                restrict: 'E',
                transclude: true,
                scope: {
                    'options': '='
                },
                templateUrl: "ltcg-table.html",
                link: function(scope, element, attr) {
                        alert(scope.$parent.options.rowCollection);
                        scope.rowCollection = scope.options.rowCollection;
                }
              }             
        });

      myApp.controller('ctrl1', one)



})();

【问题讨论】:

  • 你能解释一下为什么你在警报中尝试scope.$parent.options吗?

标签: javascript angularjs


【解决方案1】:

您已将options 添加到指令范围,因此您可以通过scope.options 直接访问它。顺便说一句,指令作用域是隔离的(使用scope: {} 表示法),所以你不能只是上去尝试读取父作用域。

【讨论】:

  • 具有隔离范围 - 还设置了 $parent 属性。不工作只是继承范围
【解决方案2】:

因此,您有一个具有隔离范围的指令。在这种情况下,链接函数中的scope 参数指的是这个范围,在你的情况下是这个下一个对象

{
    'options': '='
}

因此,当您在 html 中执行时,one.rowCollectionoptions="one.rowCollection" 值已绑定到 options 属性,因此要访问它,您应该在链接中使用 scope.options功能,仅在视图中的选项上。

还将$parent 属性设置为父范围,在您的情况下 - “ctrl1”控制器范围。所以你可以直接去controller获取你想要的东西。

当使用 controller as 语法引用保存在控制器范围内的控制器时。因此,对于访问控制器,您应该使用它的名称。

示例:

var myApp = angular.module('myApp', []);

function one() {
  this.song = "Murali";
  // alert("gg");
  this.rowCollection = [{
    firstName: 'Laurent',
    lastName: 'Renard',
    birthDate: new Date('1987-05-21'),
    balance: 102,
    email: 'whatever@gmail.com'
  }, {
    firstName: 'Blandine',
    lastName: 'Faivre',
    birthDate: new Date('1987-04-25'),
    balance: -2323.22,
    email: 'oufblandou@gmail.com'
  }, {
    firstName: 'Francoise',
    lastName: 'Frere',
    birthDate: new Date('1955-08-27'),
    balance: 42343,
    email: 'raymondef@gmail.com'
  }];
  //alert($scope.gridOptions.columnDefs[1].name);
  //alert($scope.gridOptions);
};

myApp.directive('ltcgTable', function() {

  return {
    restrict: 'E',
    transclude: true,
    scope: {
      'options': '='
    },
    templateUrl: "ltcg-table.html",
    link: function(scope, element, attr) {
      //go to controller directly
      scope.rowCollection = scope.$parent.one.rowCollection
    }
  }
});

myApp.controller('ctrl1', one)
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="ctrl1 as one">
    <ltcg-table options="one.rowCollection"></ltcg-table>
  </div>
  <script id="ltcg-table.html" type="text/ng-template">
    <table st-table="rowCollection" class="table table-striped">
      <thead>
        <tr>
          <th>first name</th>
          <th>last name</th>
          <th>birth date</th>
          <th>balance</th>
          <th>email</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td colspan="5">
            Get data from scope.options
          </td>
        </tr>
        <tr ng-repeat="row in options">
          <td>{{row.firstName}}</td>
          <td>{{row.lastName}}</td>
          <td>{{row.birthDate}}</td>
          <td>{{row.balance}}</td>
          <td>{{row.email}}</td>
        </tr>
        <tr>
          <td colspan="5">
            <hr/>
          </td>
        </tr>
        <tr>
          <td colspan="5">
            Get data saved from controller directly in link function
          </td>
        </tr>
        <tr ng-repeat="row in rowCollection">
          <td>{{row.firstName}}</td>
          <td>{{row.lastName}}</td>
          <td>{{row.birthDate}}</td>
          <td>{{row.balance}}</td>
          <td>{{row.email}}</td>
        </tr>
      </tbody>
    </table>
  </script>
</div>

【讨论】:

  • 感谢您的回复。只有当我们设置特定的控制器对象(one.rowCollection)时,上述解决方案才有效。但是,如果我有多个具有不同内容的 ctrl,例如
    ,我想要 dynamic
    那么如何在同一指令中加载不同的 ctrls 数据。
  • @klmuralimohan,如您所见,在回答中我提供了 两种 方法,如果您首先使用 - 一切正常。看第一段,注意html&lt;tr ng-repeat="row in options"&gt;
  • @klmuralimohan,我有点更新答案,现在可能更清楚了
  • 是的,它工作正常。伟大的解决方案 Grundy。非常感谢... :)
  • @klmuralimohan,这可能是smart-table 模块的问题,如您所见,在 sn-p 中我不使用它,因为不知道它是什么 :)
猜你喜欢
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-15
  • 2016-06-29
  • 2015-08-10
  • 2019-04-28
相关资源
最近更新 更多