AngularJS:如何从使用子作用域的指令设置 Controller 属性?

标签 angularjs angularjs-directive angularjs-scope

LIVE DEMO

考虑以下spinner-click指令:

指令使用:

<button class="btn btn-mini"
        ng-class="{'btn-warning': person.active, disabled: !person.active}"
        spinner-click="deleteItem($index)"
        spinner-text="Please wait..."
        spinner-errors="alerts">
  Delete
</button>

指令:

app.directive('spinnerClick', function() {
  return {
    restrict: 'A',
    scope: true,
    link: function(scope, element, attrs) {
      var originalHTML = element.html();
      var spinnerHTML = "<i class='icon-refresh icon-spin'></i> " + attrs.spinnerText;

      element.click(function() {
        if (element.is('.disabled')) {
          return;
        }

        element.html(spinnerHTML).addClass('disabled');

        scope.$apply(attrs.spinnerClick).then(function() {
          element.html(originalHTML).removeClass('disabled');
        }, function(errors) {
          element.html(originalHTML).removeClass('disabled');

          // This is ugly! Is there a better way?
          var e = scope[attrs.spinnerErrors];
          e.length = 0;
          e.push.apply(e, errors);
        });
      });
    }
  };
});

Controller :

app.controller('MainCtrl', function($scope, $q, $timeout) {
  $scope.alerts = ['First alert'];
  $scope.people = [
    { name: 'David', active: true },
    { name: 'Layla', active: false }
  ];

  $scope.deleteItem = function(index) {
    var defer = $q.defer();

    $timeout(function() {
      defer.reject(["Something 'bad' happened.", "Check your logs."]);
    }, 2000);

    return defer.promise;
  };
});

注意: spinner-click 可以与其他指令一起使用(例如本例中的 ng-class)。

如您所见,我使用一种非常讨厌的方式在指令中设置了 $scope.alerts。你能找到更好的方法来做到这一点吗?


更新:(DEMO)

我尝试像这样使用 $parse:

var errorsModel = $parse(attrs.spinnerErrors);
errorsModel.assign(scope, errors);

这不起作用。

但是,如果我有 spinner-errors="wrapper.alerts" 而不是 spinner-errors="alerts"it does work!

有没有办法避免使用包装器?

最佳答案

我认为您可以使用隔离范围更简单地做到这一点。

您应该输入:

,而不是scope: true,
scope:{
    spinnerClick:"&",
    spinnerText : "@",
    spinnerErrors: "="
 }

然后,在您的指令中直接使用 scope.spinnerClickscope.spinnerTextscope.spinnerErrors

& 用于绑定(bind)属性中定义的函数表达式并将其传递到指令的范围,@ 将绑定(bind)属性的文本值和 < em>= 将使用属性中传递的表达式设置双重绑定(bind)。

您可以在这里获得更精确的解释 http://docs.angularjs.org/guide/directive (查看长版本),这里有更清晰的解释 http://www.egghead.io/ (看看隔离示波器视频,只需要几分钟,看起来很简单)。

关于AngularJS:如何从使用子作用域的指令设置 Controller 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17512013/

相关文章:

javascript - Angular - 在 Controller 中使用值配方

angularjs - 如果没有隐藏,则为输入元素设置必需的属性

javascript - require 未正确加载模块

angularjs - 以 Angular 形式设置自定义输入验证

javascript - ng-click 图像以选中单选框

javascript - 自定义过滤器覆盖原始数据或导致无限 $digest 循环

AngularJS:在 ng-repeat 生成的范围中设置变量

javascript - AngularJS : calling a factory method within the loop

javascript - 从链接修改指令模板内的 ng-show

javascript - 如何在单页应用程序中实现 gmail 撰写窗口概念?