これは、StackOverflow に関する私の最初の投稿/質問です。改善できる点があれば、アドバイスをください :)。
それでは、問題に飛び込みましょう。
簡単にするために、コードの無関係な部分を削除し、必要なファイルのみを示しました。
//app.modules.js
if (typeof window.app == "undefined") {
window.app = angular.module("AppModule", []);
}
//app.services.js
window.app
.service("settingsOverlaySvc", function($rootScope) {
this.broadcastToggle = function() {
$rootScope.$broadcast("toggle-conf");
};
});
//settings-ctrl.js
window.app.controller("SettingsController", ["$scope", "$window", "$sce", "settingsOverlaySvc",
function($scope, $window, $sce, settingsOverlaySvc) {
$scope.visible = false;
$scope.open = false;
$scope.toggleSettings = function() {
$scope.open = !$scope.open;
};
$scope.broadcastToggle = function() {
settingsOverlaySvc.broadcastToggle();
};
$scope.$on("toggle-conf", function() {
console.log("toggle-conf received");
$scope.visible = !$scope.visible;
});
}
]);
angular.bootstrap($("div[ng-controller='SettingsController']").parent(":not(.ng-scope)"), ["AppModule"]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Appended by JS - control1.html -->
<div>
<div ng-controller="SettingsController" ng-init="visible=true">
<span class="glyphicon glyphicon-cog" ng-class="{'settings-open': open}" ng-click="broadcastToggle();toggleSettings()">COG</span>
</div>
</div>
<!-- Appended by JS - control2.html-->
<div>
<div ng-controller="SettingsController" ng-cloak>
<div ng-if="visible">
<span class="glyphicon glyphicon-cog" ng-class="{'settings-open': open}" ng-click="toggleSettings()">COG</span>
<div ng-if="open">
<div class="divControl_2">Content_2</div>
</div>
</div>
</div>
</div>
上記のスニペットは期待どおりに動作します -$broadcast
が呼び出され、すべてのコントローラーがメッセージを受信して反応します。私のアプリケーションでは、ブロードキャストはコントローラーが送信することによってのみ受信されます。この問題は、動的な HTML 挿入が原因であると思います。
要件は、ページの読み込み時にコントロールを動的にレンダリングすることです。私は次のアプローチを使用してコンテンツを生成しています。
AddWidgets: function () {
var controlContainer1 = $("<section>", {
class: "sidebar-section",
id: "ctrl1-container"
});
var controlContainer2 = $("<section>", {
class: "sidebar-section",
id: "ctrl2-container"
});
$("aside.sidebar").append(controlContainer1);
$("aside.sidebar").append(controlContainer2);
$("#ctrl1-container").load("..\\assets\\ctrls\\control1.html");
$("#ctrl2-container").load("..\\assets\\ctrls\\control2.html");
}
すべてのコントロールで同じロジックを共有しているため、同じコントローラーを使用しています。
機能、コントローラーの作成に関するガイド、モジュールとサービスの定義に関する多くの資料を読みました(これにより、注入されたサービスの作成についてのアイデアが得られ$broadcast
ます)。$emit
$rootScope
現在、角度フレームワーク( AddWidgets関数)の外で角度コンテンツを生成すると問題が発生する可能性があると考えています(@stackoverflow/a/15676135/6710729)。
スパイダーセンスアラームが発生したのは、JSFiddle の例で同様の状況 ( http://jsfiddle.net/XqDxG/2342/ ) を確認したときです-コントローラーの親子関係はありません。$$nextSibling
コントローラーの angulat スコープをのぞくと、$$prevSibling
プロパティが満たされていることがわかります。私の場合、これらは[ここ]にnull
編集されています。
問題を解決するためのガイドラインを教えてください。私はAngularJSにかなり慣れていませんが、アプリケーションを開発しているときに学習しています。