最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - In Angularjs can a controller nested inside a directive set the ng-model of the directive? - Stack Overflow

programmeradmin2浏览0评论

I have a directive that uses ng-model controller and gets it model value from the controller it's inside, "myController". I'm using transclude=true and ng-transclude. This is a general purpose directive that I want to allow my colleagues to re-use. I want to let the consumer click the button and it set ngModel value to whatever value they want but basically always some object. How do I properly set that up? I realize inside the directive I can call ngModel.$setValue or $setViewValue etc... Sorry I am still new to angularjs, specifically directives. Also should I be using a controller inside the directive? I know the object definition for directives has that ability although I don't really know how or when to leverage that. Lastly is it ok to transclude controllers into directives, as in "nestedInDirController"? Thanks for any tips, tricks, examples, or advice.

jsfiddle here

<div ng-controller="myController">
    <div foo-directive="" ng-model="viewModel.foo">
        <div ng-controller="nestedInDirController">
           <various-controls-in-here />
        </div>
    </div>
 </div>

angular.module('myApp', [])
 .directive('fooDirective', function(){ 

    var template = '<div><div ng-transclude></div> <button ng-click="someFunc()">I want to update ng-model in the directive, which in turn will update myController $scope.viewModel.foo</button></div>';
   return {
      transclude: true,
      require: '?ngModel',
      template: template,
      pile: function(tElement, tAttrs, transclude){

         return function(scope, element, attrs, ngModel){

         }
      }
    };
 });

function myController($scope){

  $scope.viewModel = { foo : { bar: 'baz'}};   
 }

function nestedInDirController($scope){


  $scope.someFunc = function(){
      alert('I was called');
      //how can I set ng-model in foo-directive from this controller?
  }

}

I have a directive that uses ng-model controller and gets it model value from the controller it's inside, "myController". I'm using transclude=true and ng-transclude. This is a general purpose directive that I want to allow my colleagues to re-use. I want to let the consumer click the button and it set ngModel value to whatever value they want but basically always some object. How do I properly set that up? I realize inside the directive I can call ngModel.$setValue or $setViewValue etc... Sorry I am still new to angularjs, specifically directives. Also should I be using a controller inside the directive? I know the object definition for directives has that ability although I don't really know how or when to leverage that. Lastly is it ok to transclude controllers into directives, as in "nestedInDirController"? Thanks for any tips, tricks, examples, or advice.

jsfiddle here

<div ng-controller="myController">
    <div foo-directive="" ng-model="viewModel.foo">
        <div ng-controller="nestedInDirController">
           <various-controls-in-here />
        </div>
    </div>
 </div>

angular.module('myApp', [])
 .directive('fooDirective', function(){ 

    var template = '<div><div ng-transclude></div> <button ng-click="someFunc()">I want to update ng-model in the directive, which in turn will update myController $scope.viewModel.foo</button></div>';
   return {
      transclude: true,
      require: '?ngModel',
      template: template,
      pile: function(tElement, tAttrs, transclude){

         return function(scope, element, attrs, ngModel){

         }
      }
    };
 });

function myController($scope){

  $scope.viewModel = { foo : { bar: 'baz'}};   
 }

function nestedInDirController($scope){


  $scope.someFunc = function(){
      alert('I was called');
      //how can I set ng-model in foo-directive from this controller?
  }

}
Share edited Jun 19, 2013 at 23:53 Hcabnettek asked Jun 19, 2013 at 23:44 HcabnettekHcabnettek 12.9k38 gold badges129 silver badges192 bronze badges 1
  • 1 nestedInDirController already has access to the properties defined on myController's scope, because the scope prototypically inherits. Inside your nestedInDirController, this works: console.log($scope.viewModel) and so does this: $scope.viewModel.foo.bar = "testing"; – Mark Rajcok Commented Jun 20, 2013 at 22:02
Add a ment  | 

2 Answers 2

Reset to default 2

http://jsfiddle/jSEba/

This is one way to satisfy your need by using event emission.

i.e. letting directive to $broadcast event into its child scope, so that transcluded child scope can catch via $on to react to the button click.

angular.module('myApp', [])
.directive('fooDirective', function(){ 
    var template = '<div><div ng-transclude></div> <button ng-click="someFunc()">I want to update ng-model in the directive, which in turn will update myController $scope.viewModel.foo</button></div>';
    return {
        transclude: true,
        template: template,
        link: function(scope, elem, attrs) {
            scope.someFunc = function() {
                scope.$broadcast('buttonclick', { valname: attrs.fooDirective });
            };
        }
    };
});

function myController($scope){
    $scope.viewModel = { foo : { bar: 'baz'}};   
}

function nestedInDirController($scope){
    $scope.$on('buttonclick', function(event, arg) {
        $scope.$eval( arg.valname + " = 'new value'");
    });
}

I'm suspecting there may be a better way, though.

This is another solution using a Shared service between the directive and the controllers.

(You could create a better service to enforce the required data structure to be shared between the controllers in that specific case, instead of the general example.)

Here is a jsfiddle http://jsfiddle/PguFh/15/ (a little updated after I wrote the code below).

index.html

<div ng-controller="myController">
    <div foo-directive="" ng-model="viewModel.foo">
        <div ng-controller="nestedInDirController">
            <pre>{{viewModel.foo|json}}</pre>
        </div>
    </div>
</div>

app.js

angular.module('myApp', [])

.factory('Shared', function() {
    var shared = {};

    return {
        set: function(value) {
            shared = value;
        },
        get: function() {
            return shared;   
       }
    }
})

.directive('fooDirective', function(Shared){ 

    var template = '<div><div ng-transclude></div> <button ng-click="shared.someFunc()">I want to update ng-model in the directive, which in turn will update myController $scope.viewModel.foo</button></div>';
    return {
        transclude: true,
        require: '?ngModel',
        template: template,
        pile: function(tElement, tAttrs, transclude){

            return function(scope, element, attrs, ngModel) {
                scope.shared = Shared.get();
            }
        }
    };
});

function myController($scope, Shared){

    $scope.viewModel = { foo : { bar: 'baz'}};  
    Shared.set({
        viewModel: $scope.viewModel,
        someFunc: function() { alert('default?'); }
    });
}

function nestedInDirController($scope, Shared){
    var shared = Shared.get();
    shared.someFunc = function(){
        alert('I was called');
        //how can I set ng-model in foo-directive from this controller?
        shared.viewModel.foo.bar = "baz.modified";
    }

}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论