私が取り組んでいるいくつかの Angularjs 機能の問題を解決するために、少し問題が発生しています。
基本的な考え方は、ユーザーがアプリの次のセクションに進む前に、特定の基準を満たす必要があるシステムがあるということです。この 1 つの例は、ユーザーが先に進むために、コメントを追加し、リンク (実際のアプリでは、これはファイルのダウンロード) をクリックする必要があることです。
ここで完全な例を見ることができます: https://jsfiddle.net/d81xxweu/10/
HTML はかなり自明であると想定し、Angular モジュールで行っていることに移ります。私のアプリの宣言と初期化は次のとおりです。
var myApp = angular.module('myApp', ['ngRoute']);
myApp.run(function ($rootScope) {
// Both of these must be met in order for the user to proceed with 'special-button'
$rootScope.criteria = {
criteria1: false,
criteria2: false
};
});
これはとても簡単です。ディレクティブとコントローラーからアクセスできるようにするために、アプリケーションのルート スコープに criteria というオブジェクトをアタッチしています。基準が満たされると、ユーザーが先に進むことができるリンクをレンダリングするディレクティブがあります。この例では、リンクのテキストが「待機中...」から「クリックして続行」に変わり、先に進むことができることを示しています。
myApp.directive('specialButton', function ($rootScope) {
return {
scope: true,
template: "<a href='#'>{{ linkText }}</a>",
replace: true,
link: function (scope, el, attrs) {
scope.linkText = 'Waiting...';
var setLinkState = function(currentCriteria) {
var criteriaMet = true;
for(var k in $rootScope.criteria) {
if($rootScope.criteria[k] == false) {
criteriaMet = false;
}
}
if(criteriaMet) {
scope.linkText = 'Click to proceed';
}
};
// Watch for changes to this object at the root scope level
$rootScope.$watchCollection('criteria', function(newValues) {
setLinkState(newValues);
});
}
};
});
したがって、このディレクティブに設定したウォッチ ステートメントをトリガーするために、このコントローラーで許可されているコメントを追加できます。
myApp.controller('comments', function ($scope, $rootScope) {
$scope.commentText = '';
$scope.comments = [];
$scope.addComment = function () {
$scope.comments.push({ commentText: $scope.commentText });
$scope.commentText = ''
// When the user adds a comment they have met the first criteria
$rootScope.criteria.criteria1 = true;
};
});
前のものは、コメントを表示/追加するためのコントローラーです。ここでは、ユーザーがコメントを追加したことを示すために、criteria1 を true に設定します。これは実際には問題なく動作し、specialButton ディレクティブの $watchCollection は期待どおりに呼び出されます。
先に進むためにクリックする必要があるリンクから同じアクションを実行しようとすると、問題が発生します。これは、コメントリスト/フォームとは異なり、このような場合、コントローラーよりもディレクティブの方が意味があると理解しているため、ディレクティブでレンダリングされます。
myApp.directive('requiredLink', function($rootScope) {
return {
scope: true,
template: "<a href='#'>Click me!</a>",
replace: true,
link: function(scope, el, attrs) {
el.bind('click', function(evt) {
evt.preventDefault();
// When the user clicks this link they have met the second criteria
$rootScope.criteria.criteria2 = true;
});
}
};
});
ここでわかるように、コントローラーと同じように $rootScope を渡します。ただし、criteria2 を true に設定すると、$watchCollection はトリガーされません。
したがって、最初にコメントを追加してから他のボタンをクリックすると、2番目の変更がウォッチをトリガーしないため、specialButtonがテキストを更新するのが見られません。ただし、最初にリンクをクリックしてからコメントを追加すると、specialButton が期待どおりに更新されます。requiredLink をクリックすると、データが更新されますが、ウォッチはトリガーされません。そのため、コメントを追加して $watch がトリガーされると、両方が true に設定されていることがわかります。
この問題を解決するために提供できるヘルプを事前に感謝します。お時間をいただきありがとうございます。