【问题标题】:Error: [$compile:nonassign] Expression 'undefined' used with directive 'myFacebook' is non-assignable错误:[$compile:nonassign] 与指令“myFacebook”一起使用的表达式“未定义”是不可分配的
【发布时间】:2014-10-26 23:19:51
【问题描述】:

我正在 angularjs 中编写指令并得到上述错误。我正在使用书中的代码。

.directive('myFacebook', [function(){
return {
    link: function(scope,element,attributes) {
        (function(d) {
                var js, id = 'facebook-jssdk',
                    ref = d.getElementsByTagName('script')[0];
                if (d.getElementById(id)) {
                    return;

                }
                js = d.createElement('script');
                js.id = id;
                js.async = true;
                js.src = "//connect.facebook.net/en_US/all.js";
                ref.parentNode.insertBefore(js, ref);
            }(document));
            // Initialize FB
            window.fbAsyncInit = function() {
                FB.init({

                    appId: 'xxxx', //birthday reminder
                    status: true, // check login status
                    cookie: true, // enable cookies to access the session
                    xfbml: false // parse XFBML
                });
                //Check FB Status
                FB.getLoginStatus(function(response) {
                     xxxx
                });
            };
        scope.username='';
    },
    scope: {
            permissions: '@',
            myFriends: '=friends'
        },
    controller: function($scope) {
        $scope.loadFriends = function() {
            FB.api('/me/friends?fields=birthday,name,picture', function(response) {
                    $scope.$apply(function() {
                        $scope.myFriends = response.data;
                    });
                });
        }
    },

    template:'Welcome {{username}}'
   }}])

我收到错误

 $scope.$apply(function() {
            $scope.myFriends = response.data;
 });

HTML 代码

<div my-facebook></div>
<h1> My Friend's Birthday Reminder</h1>
<div ng-repeat="friend in myFriends">
     {{friend.name}}
</div>

【问题讨论】:

  • 请在您使用myFacebook 指令的地方发布HTML。

标签: javascript angularjs angularjs-directive


【解决方案1】:

问题是您没有在指令元素&lt;div my-facebook&gt;&lt;/div&gt; 中定义属性friends

当你像这样定义指令的范围时:

scope: {
    permissions: '@',
    myFriends: '=friends'
}

你基本上是在说:

  • 将同名DOM属性的值绑定到本地范围的permissions属性
  • 在本地作用域的myFriends 属性和父作用域的friends 属性之间设置双向绑定

由于您没有在 DOM 中定义属性 friends,Angular 无法创建双向绑定并引发错误。更多信息here.

在你的 DOM 上定义 friends 属性,它应该可以解决问题:

<div my-facebook friends="friendList"></div>

例如,在控制器上:

app.controller('Ctrl', function($scope) {
  $scope.friendList = [];
});

【讨论】:

  • 太棒了,它就像一个魅力。也感谢您的解释。
  • 很好的解释
  • 对我来说,需要强调的是关于添加 到 DOM 的部分,我以为我已经完成了,但太久后意识到我实际上没有。
【解决方案2】:

我遇到了同样的问题,对我来说问题是 DOM 名称中的大写字符。

<div my-facebook FRIENDS="friendList"></div>

没用,但是

<div my-facebook friends="friendList"></div>

工作。我花了一天的时间来解决这个问题,偶然找到了解决方案。

【讨论】:

  • 为什么要将属性名称全部大写? :)
  • 有趣的问题,可惜我不记得了:)
【解决方案3】:

不是对 OP 问题的直接回答,但这只是发生在我身上,因此对于将来可能会在谷歌上搜索此错误的任何人来说。 这类似于 JohnP 的回答。

如果您的指令中包含 camelCase 属性,也会出现此错误。

如果你有:

&lt;div my-facebook myFriends&gt;&lt;/div&gt;

它会抛出错误。

这是因为(取自角度documentation):

Angular 规范化元素的标签和属性名称以确定哪些元素匹配哪些指令。我们通常通过区分大小写的 camelCase 规范化名称(例如 ngModel)来引用指令。然而,由于 HTML 不区分大小写,我们在 DOM 中使用小写形式引用指令,通常在 DOM 元素上使用破折号分隔的属性(例如 ng-model)。

归一化过程如下:

从元素/属性的前面去除x-data-

:-_ 分隔的名称转换为驼峰式。

所以&lt;div my-facebook myFriends&gt;&lt;/div&gt;

需要变成&lt;div my-facebook my-friends&gt;&lt;/div&gt;

【讨论】:

  • 完全相同的问题,它的角度 1.5.3 和我的属性是 noOfRowsPerPage 并且它不起作用!应该是 noofrowsperpage!!奇怪!
  • @user1829319 不应该是no-of-rows-per-page 然后在你的指令中:scope: {noOfRowsPerPage: '=' }?这样你仍然可以在你的 JavaScript 中使用 camelCase。
  • @user1829319 虽然更好的解决方案可能只是rows-per-page,甚至只是rows。使其更易于阅读。
【解决方案4】:

我的解决方案在这里更难找到,但更容易实施。我不得不将其更改为 等效的(请注意,问号使属性成为可选属性。在 1.5 之前,这显然不是必需的)。

scope: {
    permissions: '@',
    myFriends: '=?friends'
}

【讨论】:

【解决方案5】:

我有这个是因为我试图更新指令范围内的另一个变量,但没有在 html 中传递它,即使它是计算出来的,也不应该在 html 中传递

这里是一个指令作用域的例子

scope: {
  var1: '=',
  var2: '='
}

在该指令中,我可以将 var1 或 var2 传递给它,但不能同时传递给它,指令逻辑将找到另一个 var 的值

当我用 var1 调用指令并在代码中更新 var2 时发生了这个错误

<pb-my-directive  var1="something"></my-directive>

要克服这个问题,请使用您想要更新的所有范围变量调用指令,即使在我的示例中使用无意义的值

<pb-my-directive  var1="something" var2="false"></my-directive>

希望对你有帮助

【讨论】:

    【解决方案6】:

    如果您将其用作单向绑定,只需适当地定义范围:

    scope: {
       example: '<'
    }
    

    在我的例子中,我使用双向绑定作为单向绑定,传递如下内联对象:

    <directive bindings="{key: value}"></directive>
    

    我的情况很特殊,因为我(故意)破坏了对象并因此破坏了它们的绑定,但如果您只需要单向绑定,只需按这种方式定义即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-04
      • 1970-01-01
      相关资源
      最近更新 更多