2

This is my first post/question here on StackOverflow so if you see any improvement I can made - please give me an advice :).

Now let me dive into the issue.

For the sake of simplicity I removed any irrelevant portions of code and presented only necessary files.

//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>

The above snippet works as I expected - the $broadcast is called, all controllers receive the message and reacts. In my application the broadcast is received only by controller sending it. I think the problem is caused by dynamic HTML insertions.

The requirement is to render controls dynamically on page load. I'm using the following approach to generate content.

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

I'm using the same controller because it shares the same logic for all controls.

I've read a lot materials about $broadcast and $emit functionality, guides on creating controllers, defining modules and services (that one gives me idea about creating service with $rootScope injected).

Now I'm thinking that generating angular content outside angular framework (AddWidgets function) can cause the problem (@stackoverflow/a/15676135/6710729).

What raised my spider sense alarm is when I've checked the JSFiddle example for the similar situation (http://jsfiddle.net/XqDxG/2342/) - no parent-child relation of controllers. When I peek at angulat scope of the controllers I can see that $$nextSibling and $$prevSibling properties are filled. In my case these are nulled [here].

Can you give me some guidelines how can I resolve my issue? I'm fairly new to AngularJS and learning as I'm developing the application.

  • don't use jquery load for this. use a router! – Daniel A. White Nov 18 '16 at 13:47
  • Wait a second. Are you trying to dynamically load some HTML and add it to your application with a predefined controller? – Dennis Baizulin Nov 18 '16 at 20:09
  • @DanielA.White from my understanding routing is used to create single page apps - so it can reload whole page seamlessly, isn't it? I only need to insert small portions of HTML on the page. @Dennis That's exactly what I'm doing right now, if I understand the "predefined controller" phrase correctly. The controller is defined in *.js file that is referenced in HTML file that I'm loading dynamically. And there is a `ng-controller` attribute in the mentioned HTML. – Kamil Gierach-Pacanek Nov 20 '16 at 07:17

0 Answers0