2016-10-14 4 views
2

スコープがディレクティブに継承されているが、分離されていない場合は、ng-clickを動作させることができます。ここでUPDATE: The point is that I want the click function to be defined as part of the directive... moving the function definition into a different scope is not what I want.スコープが分離されたディレクティブにng-clickを使用するにはどうすればよいですか?

は継承された範囲での作業例です: はhttps://codepen.io/anon/pen/PGBQvj

ここで分離されたスコープで壊れた例です。 https://codepen.io/anon/pen/jrpkjp

(数字をクリックして、彼らは最初の例ではなく、第二にインクリメント)

いくつかのコード...

HTML

<div ng-app="myApp" ng-controller="baseController"> 
    <my-directive ng-click="hello()" current="current"></my-directive> 
</div> 

ディレクティブ継承されたスコープを持ちます:

angular.module('myApp', []) 
    .controller('baseController', function($scope) { 
    $scope.current = 1; 
    }) 
    .directive('myDirective', function() { 
    return { 
     link: function(scope, element, attrs) {  
     scope.hello = function() { 
      scope.current++ 
     }; 
     }, 
     replace: true, 
     scope: true, 
     template: '<div><child>  <strong>{{ current }}</strong></child></div>' 
    } 
    }) 
    .directive('child', function() { 
    return { 
     link: function(scope, element, attrs) { 
     console.log("horeee"); 
     } 
    } 
    }); 

分離された範囲と同じディレクティブ:孤立ディレクティブで

angular.module('myApp', []) 
    .controller('baseController', function($scope) { 
    $scope.current = 1; 
    }) 
    .directive('myDirective', function() { 
    return { 
     link: function(scope, element, attrs) {  
     scope.hello = function() { 
      scope.current++ 
     }; 
     }, 
     replace: true, 
     scope: { 
     current:'=' 
     }, 
     template: '<div><child>  <strong>{{ current }}</strong></child></div>' 
    } 
    }) 
    .directive('child', function() { 
    return { 
     link: function(scope, element, attrs) { 
     console.log("horeee"); 
     } 
    } 
    }); 

答えて

1

問題は、あなたが定義されていない関数を呼び出すしようとしているです。独立したディレクティブの内部でロジックを定義したい場合は、関数リファレンスを渡す必要はありません。

<my-directive current="current"></my-directive> 

ここにng-click="hello()"を渡すことはできません。これはコントローラのスコープなので、hello()は未定義です。

その代わり、ディレクティブ

template: '<div ng-click="hello()"> 

1つの追加ポイントのテンプレートにng-clickイベントを移動: あなたはディレクティブのlink()機能を使用しています。これはDOM操作用に予約されています。代わりに、controller関数内でhello()を定義してください。

controller: function ($scope) { 
    $scope.hello = function() { 
     $scope.current++ 
    } 
}, 

ここでは、より大きなアーキテクチャ上の問題があると思います。分離されたディレクティブまたはコンポーネントのポイントは、内部のロジックをカプセル化することです。それは外部の状態を操作すべきではありません。この例では、数字を増やしています。アプリケーションの別の部分で数値を減分する場合はどうなりますか?デクリメントロジックを含むディレクティブをコピーすると、コードの重複が多く発生します。

代わりに、コントローラの増分または減分の機能を定義し、それを指令に渡す必要があります。

scope: { 
    current:'=', 
    changeNumber: '&' 
}, 

とテンプレートからchangeNumberを呼び出します。そして、

<my-directive change-number="increment()" current="current"></my-directive> 

は、指令への関数の参照をバインドする&構文を使用します。コードの再利用が非常に容易になります。

-1

は、あなたの代わりにng-click="hello()"ng-click="$parent.hello()"使用することができます。あなたの質問にペンを投稿するのは良いです。

説明:ng-clickを要素に使用すると、その値(hello())は、その外側の範囲、つまり例のコントローラの範囲に対して相対的に評価されます。非孤立スコープを使用するディレクティブを作成すると、コントローラのスコープはlink関数に渡され、コントローラのスコープにはhelloが定義されます。

//編集コード:

angular.module('myApp', []) 
    .controller('baseController', function($scope) { 
    $scope.current = 1; 
    $scope.hello =() => $scope.current ++; 
    }) 
    .directive('myDirective', function() { 
    return { 
     link: function(scope, element, attrs) {  
     }, 
     replace: true, 
     scope: { 
     current:'=' 
     }, 
     template: '<div><child>  <strong>{{ current }}</strong></child></div>' 
    } 
    }) 
    .directive('child', function() { 
    return { 
     link: function(scope, element, attrs) { 
     console.log("horeee"); 
     } 
    } 
    }); 
+1

ペンで試してみましたか?動作しません。 – geoidesic

+0

申し訳ありませんが、私はあなたの質問を誤解しています。あなたのコントローラのスコープに 'hello()'を定義するとうまくいくはずです。@ geoidesic – Zen

+0

これはうまくいきません。提案する前に試してください:) tx。 – geoidesic

0

は、コントローラにハロー機能を追加します。それは現在の値を更新してみましょうと

変化をディレクティブにあなたは、コントローラからオブジェクトを渡す必要

CodePen

0

指令

.controller('baseController', function($scope) { 
    $scope.current = 1; 
    $scope.hello = function() {   
     $scope.current++; 

    }; 

})の単離された範囲の中にそれを渡しますあなたのjsを

angular.module('myApp', []) 
.controller('baseController', function($scope) { 
$scope.current = {}; 
$scope.current.val=1; 
}) 
.directive('myDirective', function() { 
return { 
    link: function(scope, element, attrs) {  scope.internalcurrent= scope.current || {}; 
             //scope.internalcurrent.val=1; 
    scope.internalcurrent.hello = function() { 
     scope.internalcurrent.val++ 

    }; 
    }, 
    replace: true, 
    scope: { 
    current:'=' 
    }, 
    template: '<div><child>  <strong>{{ internalcurrent.val }}</strong></child></div>' 
} 
}) 
.directive('child', function() { 
return { 
    link: function(scope, element, attrs) { 
    console.log("horeee"); 
    } 
} 
}); 

に、あなたのhtm

<div ng-app="myApp" ng-controller="baseController"> 
<my-directive ng-click="hello()" current="current"></my-directive> 
</div> 
0

へリットルあなたはクリック機能は、ディレクティブ内で定義されるようにしたいなら、あなたはこのようなテンプレートの中にハンドラをアタッチする必要があります。

template: '<div ng-click="hello()"><child><strong>{{current}}</strong></child></div>' 

あなたはディレクティブ宣言にハンドラをアタッチあなたの壊れた例のように、現在のスコープ(コントローラのスコープ)で関数を呼び出すことを基本的にng-clickに指示しています。実際の例では、関数はmyDirective内から定義されていましたが、スコープに実際に接続されていたので、この場合(実際の例)はコントローラのスコープでした。

CodePen

関連する問題