指令attr内部的回调函数定义在不同的attr中

fxc*_*xck 38 javascript ajax angularjs angularjs-directive

所以我有这个名为say的指令mySave,它就是这个

app.directive('mySave', function($http) {
   return function(scope, element, attrs) {
      element.bind("click", function() {
          $http.post('/save', scope.data).success(returnedData) {
              // callback defined on my utils service here

              // user defined callback here, from my-save-callback perhaps?
          }
      });
   }
});
Run Code Online (Sandbox Code Playgroud)

元素本身看起来像这样

<button my-save my-save-callback="callbackFunctionInController()">save</button>
Run Code Online (Sandbox Code Playgroud)

callbackFunctionInController现在只是

$scope.callbackFunctionInController = function() {
    alert("callback");
}
Run Code Online (Sandbox Code Playgroud)

当我console.log() attrs.mySaveCallback在my-save指令里面时,它只是给了我一个字符串callbackFunctionInController(),我在某个地方读到我应该解析它并且它会没问题,所以我试着给$parse(attrs.mySaveCallback)了我一些函数,但几乎没有我想要的那个,它让我回来了

function (a,b){return m(a,b)} 
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?这种方法从一开始就有缺陷吗?

fxc*_*xck 61

因此,最好的方法是使用ProLoser建议的隔离范围

app.directive('mySave', function($http) {
   return {
      scope: {
        callback: '&mySaveCallback'
      }
      link: function(scope, element, attrs) {
        element.on("click", function() {
            $http.post('/save', scope.$parent.data).success(returnedData) {
                // callback defined on my utils service here

                scope.callback(); // fires alert
            }
        });
      }
   }
});
Run Code Online (Sandbox Code Playgroud)

要将参数传递回控制器,请执行此操作

[11:28] <revolunet> you have to send named parameters 
[11:28] <revolunet> eg my-attr="callback(a, b)" 
[11:29] <revolunet> in the directive: scope.callback({a:xxx, b:yyy})
Run Code Online (Sandbox Code Playgroud)

  • @ArunPJohny,不使用双向绑定的一个原因:有时您不希望为回调函数仅需要的值添加其他范围属性. (2认同)
  • 这记录在哪里? (2认同)

Pro*_*ser 12

有很多方法可以解决你正在做的事情.你应该知道的第一件事是,$http.post()一旦DOM元素被模板引擎渲染出来就会被调用,就是这样.如果你把它放在重复内,那么将对转发器中的每个新项目进行调用,所以我猜这绝对不是你想要的.如果是,那么你真的没有正确设计东西,因为仅存在DOM不应该指示对后端的查询.

无论如何,直接回答你的问题; 如果您在$ parse上阅读虽然糟糕的文档,它会返回一个评估表达式.通过将范围传递给evaluate on来执行此函数时,将返回您传递的范围上该表达式的当前状态,这意味着您的函数将被执行.

var expression = $parse(attrs.mySave);
results = expression($scope); // call on demand when needed
expression.assign($scope, 'newValu'); // the major reason to leverage $parse, setting vals
Run Code Online (Sandbox Code Playgroud)

是的,一开始有点令人困惑,但你必须明白异步应用程序中的$ scope会不断变化,而这一切都与你想要确定的价值有关,而不仅仅是如何.$parse对于您希望能够为其分配值的模型的引用更有用,而不仅仅是从中读取.

当然,您可能想要阅读有关创建隔离范围或如何$eval()表达式的信息.

$scope.$eval(attrs.mySave);
Run Code Online (Sandbox Code Playgroud)

  • @foxx,在你的链接函数中使用如下解析:`var cb = $ parse(attrs.mySaveCallback);`,然后在你的click回调中:`cb(scope);`.[小提琴](http://jsfiddle.net/mrajcok/Qak5u/) (2认同)

Aru*_*hny 9

您可以使用.$ eval在给定范围内执行语句

app.directive('mySave', function($http) {
   return function(scope, element, attrs) {
      $http.post('/save', scope.data).success(returnedData) {
          // callback defined on my utils service here

          // user defined callback here, from my-save-callback perhaps?
          scope.$eval(attrs.mySaveCallback)
      }
   }
});
Run Code Online (Sandbox Code Playgroud)

TD:演示

如果要在指令和控制器之间共享数据,可以使用双向绑定

app.controller('AppController', function ($scope) {
   $scope.callbackFunctionInController = function() {
      console.log('do something')
   };

   $scope.$watch('somedata', function(data) {
      console.log('controller', data);
   }, true);
});

app.directive('mySave', function($http, $parse) {
   return {
     scope: {
       data: '=mySaveData',
       callback: '&mySaveCallback' //the callback
     },
     link: function(scope, element, attrs) {
       $http.get('data.json').success(function(data) {
         console.log('data', data);
         scope.data = data;
         scope.callback(); //calling callback, this may not be required
       });
     }
   };
});
Run Code Online (Sandbox Code Playgroud)

演示:小提琴