Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to modify scope from within a directive in AngularJs

I need to modify a root scope attribute from within a callback inside a directive. But the directive is in a inner scope created by a switch directive.

HTML

<div ng-app="app" ng-controller='AppController'>     <p>Selected: {{ selected }}</p>     <div ng-switch on="selected">         <div ng-switch-default>             <p>Item: {{ selected }}</p>             <custom-tag selected-item="selected" />         </div>         <div ng-switch-when="New value">             <p>Worked</p>         </div>     </div> </div> 

JavaScript

angular.module('app', [])         .directive("customTag", [function () {     return {         restrict: "E",         replace: true,         template: "<input type='button' value='Click me' />",          link: function (scope, element, attrs) {             element.bind('click', function () {                 scope[attrs.selectedItem] = "New value";                 scope.$apply();             });         }     }; }]);  function AppController($scope) {     $scope.selected = 'Old value'; } 

Fiddle: http://jsfiddle.net/nJ7FQ/

My objective is to be able to display "New value" in the Selected area. How can I accomplish what I am trying to do? What am I doing wrong?

Besides, as I am trying to make a component. Is there a way to do the same but with an isolated scope?

like image 254
Fernando Avatar asked Jul 10 '13 02:07

Fernando


People also ask

How I use scope in a directive AngularJS?

The directive scope uses prefixes to achieve that. Using prefixes helps establish a two-way or one-way binding between parent and directive scopes, and also make calls to parent scope methods. To access any data in the parent scope requires passing the data at two places – the directive scope and the directive tag.

What is the scope of scope in AngularJS?

AngularJS Scope The scope is the binding part between the HTML (view) and the JavaScript (controller). The scope is an object with the available properties and methods. The scope is available for both the view and the controller.

What is scope in custom directive?

In an AngularJS directive the scope allows you to access the data in the attributes of the element to which the directive is applied. This is illustrated best with an example: <div my-customer name="Customer XYZ"></div> and the directive definition: angular. module('myModule', []) .

What is isolate scope in AngularJS?

Isolated scope directive is a scope that does not inherit from the parent and exist on its own. Scenario: Lets create a very simple directive which will show the object from the parent controller.


2 Answers

I updated the fiddle, basically had to go to the parent to get the right "selected" variable, also used the isolate scope = to get two way binding between the value passed in and the internal model.

http://jsfiddle.net/nJ7FQ/2/

angular.module('app', [])      .directive("customTag", [function () {     return {         restrict: "E",         replace: true,         template: "<input type='button' value='Click me' />",         scope: {model:'='},          link: function (scope, element, attrs) {             element.bind('click', function () {                 scope.model[attrs.selectedItem] = "New value";                 scope.$apply();             });         }     }; }]);  function AppController($scope) {     $scope.selected = 'Old value'; } 

and the HTML

<div ng-app="app" ng-controller='AppController'>     <p>Selected: {{ selected }}</p>     <div ng-switch on="selected">         <div ng-switch-default>             <p>Item: {{ selected }}</p>             <custom-tag selected-item="selected" model="$parent" />         </div>         <div ng-switch-when="New value">             <p>Worked</p>         </div>     </div> </div> 

Updated the fiddle to use your original reading of the property from the attribute: http://jsfiddle.net/nJ7FQ/4/

like image 141
shaunhusain Avatar answered Sep 26 '22 23:09

shaunhusain


I improved the jsfiddle a bit:

angular.module('app', [])      .directive("customTag", ['$parse', function ($parse) {     return {         restrict: "E",         replace: true,         template: "<input type='button' value='Click me' />",          link: function (scope, element, attrs) {             element.bind('click', function () {                 scope.$apply(function () {                     $parse(attrs.selectedItem).assign(scope.$parent, "New value");                 });             });         }     }; }]);  function AppController($scope) {     $scope.selected = { 'foo': 'Old value' }; } 

http://jsfiddle.net/nJ7FQ/15/

This way, the scope value, you want to change can also be an object property like selected.foo in the example. Also, I removed the scope parameter and told the directive to always use the parent scope. And finally I wrapped the click handler into the $apply callback (see here for example). Better would be, of course, to use ngClick instead of the element.bind().

like image 21
stofl Avatar answered Sep 23 '22 23:09

stofl