2016-01-09 24 views
9

私は、ボタンフォームを配置するために使用する角度の指示を持っています。テンプレートは、ユーザーがそれを見る必要があるまで隠されています。これは単体で動作するシンプルなテンプレートですが、大きなフォームに結合するとテンプレートが表示されません。私はこれを実行すると角のないテンプレートがng-hideで表示されない

<tr ng-show="rowsShown >= 2"><td>Search by:</td><td><div button-toggle my-btn-arr=0></div><select ng-model="selection2" ng-options="option.text for option in options"></select><input type="text" size="20" ng-model="queryF2"><ng-md-icon icon="add_circle_outline" style="fill:#a9a9a9" ng-click="addSearchField();"></ng-md-icon> <ng-md-icon icon="remove_circle_outline" style="fill:#a9a9a9" ng-click="removeSearchField();"></ng-md-icon></td></tr> 

.directive('buttonToggle', function() { 
       return { 
        restrict: 'A', 
        scope: { 
         myBtnArr: "=" 
        }, 
        template: '<button ng-click="click()">{{ myBtnTxt[myBtnArr] }}</button>', 
        link: function(scope) { 
         scope.myBtnTxt = ["AND", "OR", "NOT"]; 
         scope.click = function() { 
          scope.myBtnArr = (scope.myBtnArr < 2 ? scope.myBtnArr + 1 : 0); 
         } 
        } 
       }; 
      }); 

そして、作品のhtml:

<div button-toggle my-btn-arr=0></div> 

と動作しませんHTMLスニペットここ

はディレクティブですhtmlの部分(これはテンプレートと無関係なコントローラによって制御されます)では、私はこのエラーを受け取ります:

Error: [$compile:nonassign] Expression '0' used with directive 'buttonToggle' is non-assignable! 

そのテンプレート機能を範囲内にまとめてください。いいえ。私は

link: function(scope) { 
      scope.myBtnTxt = ["AND", "OR", "NOT"]; 
      scope.click = function() { 
       scope.$apply (function() { 
        scope.myBtnArr = (scope.myBtnArr < 2 ? scope.myBtnArr + 1 : 0); 
       }) 
      } 
     } 

が、私はこのエラーが出る...それを行うとき:

Error: [$rootScope:inprog] $apply already in progress 

だから、それは明らかに間違ってスコープを包んで問題だが、それを修正する方法がわかりません。何かご意見は?

答えて

7

それはあなたがmy-btn-arrのために2つの結合方法を作成したくないように見えます。既存の変数にバインドするのではなく、ディレクティブにデータを渡したい場合は、属性引数linkから読み取ります。

.directive('buttonToggle', function() { 
    return { 
     restrict: 'A', 
     scope: {}, 
     template: '<button ng-click="click()">{{ myBtnTxt[myBtnArr] }</button>', 
     link: function(scope, elem, attr) { 
     scope.myBtnArr = attr.myBtnArr; 
     scope.myBtnTxt = ["AND", "OR", "NOT"]; 
     scope.click = function() { 
      scope.myBtnArr = (scope.myBtnArr < 2 ? scope.myBtnArr + 1 : 0); 
     } 
     } 
    } 
    }); 

変数を入力として渡す可能性がある場合は、$parseを使用します。

// This won't work with an isolated scope, inherit from parent scope instead 
scope : true, 
link: function(scope, elem, attr) { 
    // this will evaluate the expression against the scope 
    scope.myBtnArr = $parse(attr.myBtnArr)(scope); 
} 

今、あなたはあなたが本当に2つの結合方法を使用したい場合は、戻っ表現my-btn-arrで定義されたパスに値を書き込むことが可能でなければならない

<div button-toggle my-btn-arr="0"></div> 
<div button-toggle my-btn-arr="view.myValue"></div> 

としてディレクティブを使用することができます。それで、あなたはscope: { myBtnArr: "=" }使用する場合は、このような書き込み可能な式でディレクティブを使用する必要があります。

<div button-toggle my-btn-arr="view.myValue"></div> 
<!-- "0" is not assignable--> 
<div button-toggle my-btn-arr="0"></div> 

http://jsfiddle.net/Lw7ckt9x/1/

+0

これは私が間違っていたかもしれないところの私の推測でした...私はこれを試してみましょう。 –

+0

それは働いた!そしてあなたが正しいです、私は片方向バインディングが必要でした。ありがとう! –

3

リンク機能を使用するのではなく、コントローラー機能で同じことを試みてください。あなたが必要とする機能のためにDOM操作をしているときに、リンク機能は必要です。

+0

ちょうどので、私は、私はDOM操作をしていますかなり確信して、理解しています。ユーザーがそのボタンをクリックすると、3つの異なる状態間を移動します。私はまた、このテンプレートから追加されたボタンの数を柔軟にする必要があるので、ユーザーは必要な数だけ追加することができます。 –

+0

クリック機能の中で、あなたはちょうどmyBtnArrにいくつかの状態を設定しています、DOMはAngularによって変更されます。コントロールを見つけたり、このようなテキストを設定したりするような伝統的なDOM操作を行う場合は、Link関数で行う必要があります。ここで、ボタンのテキストは、Angularでサポートされている双方向のデータバインディングのために変更されています。 –

2

ngdocsでこのエラーを見てください。

<div button-toggle my-btn-arr=0></div> 

しかし0が割り当て可能ではありません。

あなたはこれを使用します。あなたはあなたがこのようなプレーンな0 の代わりに0の値で変数を渡す必要が0 = 1;

行うことはできません意味:

<div button-toggle my-btn-arr="obj.myvar"></div> 
関連する問題