5

I'm trying to edit view outside ng-controller element. I was able to solve it by using $rootScope and dom manipulations, but I want to know how it can be solved by native angularjs?

Html:

  <body>
    <div class="container">
      <div class="block" ng-controller="BlockController as block">
          <div><strong>Name:</strong> {{ block.name }}</div>
          <a href ng-click="block.edit()">Edit</a>
      </div>
    </div>
    
        
    <div class="container-editor">
      <div id="block-editor"></div>
    </div>
  </body>

Js:

  angular.module('app', [])

  .controller('BlockController', BlockController);

  function BlockController($compile, $scope)
  {
      this.name = 'default name';

      this.edit = function() {
          var $editor_html = ' <input type="text" ng-model="block.name" name="name" /> <a href ng-click="block.save()">Save</a>';

          $editor_html = $compile($editor_html)($scope);
          angular.element(document.querySelector("#block-editor")).html('').append($editor_html);
      };

      this.save = function() {
          // save block
          angular.element(document.querySelector("#block-editor")).html('');
      };

  }

plnkr

here is example

Community
  • 1
  • 1
Webeith
  • 303
  • 1
  • 7
  • Is there a problem with keeping the editing input tag within the controller? – aa333 Dec 15 '14 at 14:47
  • Did you know you can create multiple scopes in your Angular application, one nested inside another? Then give each one its own controller so you can implement this "the Angular way". – Blazemonger Dec 15 '14 at 15:02
  • Thanks. @Blazemonger can you show example with multiple scopes? – Webeith Dec 15 '14 at 16:37
  • You add `ng-controller="something"` to an outer div and `ng-controller="somethingelse"` to an inner div. Then use `$scope.$parent` if you want to access the parent scope from the child controller. [See this question for more.](http://stackoverflow.com/questions/21453697/angularjs-access-parent-scope-from-child-controller) – Blazemonger Dec 15 '14 at 16:58

1 Answers1

0

More angular way? Just use directives. Basically, you can get a controller(s)* of a parent directive inside a child directive. Treat parent controller as an API for its child / children.

.directive('parent', function() {
  return {
    controller: function() {
      this.catchChild = function(child) {
          // code...
      };
    }
  };
})
.directive('child', function() {
  return {
    require: '^parent',
    link: function($scope, $element, $attrs, parentController) {
      $scope.jump = function() {
        // I'm jumping...
        parentController.catch($scope);
      };
    }
  };
})

I updated your plnkr for you: http://plnkr.co/edit/qRURHRMWt9K5acLWmCHv?p=preview

(*) You can pass multiple directives as an array

angular.module('app', [])
.directive('parent1', function() {
    return {
        controller: function() {
            this.fn1 = function(child) {
                // code...
            };
        }
    };
})
.directive('parent2', function() {
    return {
        controller: function() {
            this.fn2 = function(child) {
                // code...
            };
        }
    };
})
.directive('child', function() {
    return {
        require: ['^parent1', '^parent2'],
        link: function($scope, $element, $attrs, controllers) {
            var parent1Controller = controllers[0];
            var parent2Controller = controllers[1];
            parent1Controller.fn1();
            parent2Controller.fn2();
        }
    };
})
Dawid Karabin
  • 5,113
  • 1
  • 23
  • 31