2

ライブデモ

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);
        });
      });
    }
  };
});

コントローラ:

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、非常に厄介な方法でディレクティブを設定しています。これを行うためのより良い方法を見つけることができますか?


更新: (デモ)

私は$parseこのように使用しようとしました:

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

これは機能しません。

しかし、私が持っているのspinner-errors="wrapper.alerts"ではなくspinner-errors="alerts"それはうまくいきます!

ラッパーの使用を避ける方法はありますか?

4

5 に答える 5

3

分離スコープを使用すると、より簡単に実行できると思います。

の代わりにscope: true,、次のように入力する必要があります。

scope:{
    spinnerClick:"&",
    spinnerText : "@",
    spinnerErrors: "="
 }

次に、ディレクティブで , , を直接使用scope.spinnerClickscope.spinnerTextますscope.spinnerErrors

&は、属性で定義された関数式をバインドしてディレクティブのスコープに渡すために使用されます。@は属性のテキスト値をバインドし、=は属性に渡された式で二重バインディングを設定します。

より正確な説明はこちらhttp://docs.angularjs.org/guide/directive (長いバージョンを参照) で、より明確な説明はhttp://www.egghead.io/ (isolate を参照) で確認できます。ビデオをスコープすると、数分しかかからず、非常にシンプルに見えます)。

于 2013-07-11T14:26:44.343 に答える
0

あなたは $parse について正しい考えを持っていました。問題は、エラーの新しい配列を子スコープに割り当てていることです。これにより、親/コントローラースコープの配列が非表示になります (ただし、置き換えられません)。

あなたがしなければならないことは、親配列への参照を取得してから、内容を置き換えることです (元のバージョンで行っていたように)。ここ を参照してください

于 2013-07-11T17:08:11.137 に答える