angularjs share data config between controllers

后端 未结 4 935
予麋鹿
予麋鹿 2020-11-28 15:52

I\'m wondering what could be a good way to share directive between controller. I\'ve got ie two directives to use in different controller with different configuration the fi

相关标签:
4条回答
  • 2020-11-28 16:02

    What you want is terrible.

    You wouldn't want your controllers to know anything about each other, let alone, one having access to the function of the other. You can just use a Service to achieve that. As for using directives, not sure what exactly you want to happen.

    As for your second thing, you can as easily do this

    .service('MyTestService', function(){
        return {
           testScope: function(){
               console.log('It works');
           }
        };
    })
    
    .controller('MyController', ['$scope', 'MyTestService', function($scope, MyTestService){
       $scope.testScope = MyTestService.testScope;
    }])
    

    and in your view:

    <p ng-click="testScope()">ppp</p>
    
    0 讨论(0)
  • 2020-11-28 16:07

    Consider the method described by this post: Extending AngularJS Controllers Using the Mixin Pattern

    Instead of copying your methods out of a service, create a base controller that contains those methods, and then call extend on your derived controllers to mix them in. The example from the post:

    function AnimalController($scope, vocalization, color, runSpeed) {
    
        var _this = this;
    
        // Mixin instance properties.
        this.vocalization = vocalization;
        this.runSpeed = runSpeed;
    
        // Mixin instance methods.
        this.vocalize = function () {
            console.log(this.vocalization);
        };
    
        // Mixin scope properties.
        $scope.color = color;
    
        // Mixin scope methods.
        $scope.run = function(){
            console.log("run speed: " + _this.runSpeed );
        };
    }
    

    Now we can mixin AnimalController into DogController:

    function DogController($scope) {
    
        var _this = this;
    
        // Mixin Animal functionality into Dog.
        angular.extend(this, new AnimalController($scope, 'BARK BARK!', 'solid black', '35mph'));
    
        $scope.bark = function () {
            _this.vocalize(); // inherited from mixin.
        }
    }
    

    And then use DogController in our template:

    <section ng-controller="DogController">
        <p>Dog</p>
    
        <!-- Scope property mixin, displays: 'color: solid black' -->
        <p ng-bind-template="color: {{ color }}"></p>
    
        <!-- Calls an instance method mixin, outputs: 'BARK BARK!' -->
        <button class="btn" ng-click="bark()">Bark Dog</button>
    
        <!-- Scope method mixin, outputs: 'run speed: 35mph' -->
        <button class="btn" ng-click="run()">Run Dog</button>
    </section>
    

    The controllers in this example are all in the global space and are included in the markup as follows.

    <script type="text/javascript" src="lib/jquery.js"></script>
    <script type="text/javascript" src="lib/angular.js"></script>
    <script type="text/javascript" src="app/controllers/animal-controller.js"></script>
    <script type="text/javascript" src="app/controllers/dog-controller.js"></script>
    <script type="text/javascript" src="app/controllers/cat-controller.js"></script>
    <script type="text/javascript" src="app/app.js"></script>
    

    I haven't tested it, but I don't see why the following wouldn't work:

    var myApp = angular.module('myApp', [])
    
    .controller('AnimalController', ['$scope', 'vocalization', 'color', 'runSpeed', function ($scope, vocalization, color, runSpeed) { /* controller code here */}]);
    
    .controller('DogController', ['$scope', '$controller', function($scope, $controller) {
        var _this = this;
    
        // Mixin Animal functionality into Dog.
        angular.extend(this, $controller('AnimalController', {
             $scope: scope,
             vocalization: 'BARK BARK!', 
             color: 'solid black', 
             runSpeed:'35mph' 
        }));
    
        $scope.bark = function () {
            _this.vocalize(); // inherited from mixin.
        }
    }]);
    

    see: docs for $controller service

    0 讨论(0)
  • 2020-11-28 16:09

    I ended up with:

    //service
    .service('PostUploader',function($upload){
            var that = this;
            var fileReaderSupported = window.FileReader !== null;
            this.notify = null;
            this.success = null;
            this.showAlert = false;
            this.avatar = '';
            this.onFileSelect = function($files) {
                var $file = $files[0];
                var filename = $file.name;
                this.avatar = filename;
                var isImage = /\.(jpeg|jpg|gif|png)$/i.test(filename);
                if(!isImage){
                    this.showAlert = true;
                    return;
                }
                this.showAlert = false;
                if (fileReaderSupported && $file.type.indexOf('image') > -1) {
                    var fileReader = new FileReader();
                    fileReader.readAsDataURL($file);
                    fileReader.onload = that.notify;
                }
                $upload.upload({
                    url :'/api/post/upload',
            method: 'POST',
            headers: {'x-ng-file-upload': 'nodeblog'},
            data :null,
            file: $file,
            fileFormDataName: 'avatar'
                })
                .success(that.success)
                .progress(function(evt) {
    
                })
                .error(function(data, status, headers, config) {
                    throw new Error('Upload error status: '+status);
                })
    
            };
            this.closeAlert = function() {
                this.showAlert = false;
            };
        })    
    
    //controller
     /* Uploader post */
            $scope.dataUrl = null;
            $scope.avatar = PostUploader.avatar;
            $scope.showAlert = PostUploader.showAlert;
            $scope.onFileSelect = PostUploader.onFileSelect;
            $scope.closeAlert = PostUploader.closeAlert;
            PostUploader.notify = function(e){
                $timeout(function() {
                    $scope.dataUrl = e.target.result;
                });
            };
            PostUploader.success = function(data, status, headers, config) {
               $timeout(function() {
                    $scope.post.avatar = data.url;
                });
            }
            $scope.$watch('avatar',function(newVal, oldVal){
                if(newVal) { 
                    $scope.avatar = newVal;
                }  
            }); 
            $scope.$watch('showAlert',function(newVal, oldVal){
                $scope.showAlert = newVal;
                $scope.dataUrl = null;
            }); 
    

    I did so because I've to do the same thing in create post and edit post but all in all I've got quite the same repeated code ! :)

    The only good thing is the code has got less logic.

    0 讨论(0)
  • 2020-11-28 16:21

    obvious but brilliant solution (may be)

    (function(window, angular, undefined) {
                    'use strict';
                    angular.module('ctrl.parent', [])
                        .run(function ($rootScope) {
                            $rootScope.test = 'My test'   
                            $rootScope.myTest = function(){
                                alert('It works');
                            }
                    });
                })(window, angular);
                angular.module('app',['ctrl.parent'])
                    .controller('ChildCtrl', function($scope){
    
                });
    

    It's easy and clean and don't see any drawback(it's not global)

    UPDATE

    'use strict';
                    (function(window, angular, undefined) {
                        'use strict';
                        angular.module('ctrl.parent', [])
                            .controller('ParentController',function (scope) {
                                scope.vocalization = '';
                                scope.vocalize = function () {
                                    console.log(scope.vocalization);
                                };
                        });
                    })(window, angular);
                    angular.module('app',['ctrl.parent'])
                        .controller('ChildCtrl', function($scope,$controller){
                        angular.extend($scope, new $controller('ParentController', {scope:$scope}));
    $scope.vocalization = 'CIP CIP';
                    });
    

    just a little neater and it works CIP CIP :)

    0 讨论(0)
提交回复
热议问题