angularjs - Controller inheritance with injection -
i'm having hard time trying understand best way achieve inheritance controllers. i've seen few other posts here these still don´t things.
here's have: - 2 controllers 80% similar. have factory both use data displayed. - use controlleras notation, var vm = this
- there's mix of vars , functions used in view , therefore created inside vm, , other internal vars , functions not. - tried create single parent controller , use injection create these 2 controllers, overwriting need, not working expected , i'm not sure right thing do
here simplified version of code.
(function() { angular .controller('parentcontroller', parentcontroller) parentcontroller.$inject = [ '$scope', '$location' ]; function parentcontroller($scope, $location) { var vm = this; // view model var url = $location.url(); var isdataloaded = false; vm.predicate = 'order'; vm.reverse = false; vm.results; vm.isdataready = isdataready; vm.setorder = setorder; function isdataready() { return isdataloaded; } function setorder(p) { vm.reverse = (p === vm.predicate) ? !vm.reverse : false; vm.predicate = p; } $scope.$on('read.finished', function() { isdataloaded = true; }) } })();
-
(function() { angular .controller('childcontroller', childcontroller) childcontroller.$inject = ['$controller', '$scope', 'myfactory']; function childcontroller($controller, $scope, myfactory) { $controller('parentcontroller', {$scope: $scope}); var template = 'screen'; // ************** m n ************** myfactory.getresults(url, vm); } })();
this working expected.
when inject childcontroller parentcontroller, need inject $scope? i'm using vm. also, need inject $location? in example when execute code i'm forced use var url = $location.url();
again in childcontroller, expected inherite value parentcontroller.
so thing is, getting values $scope if work this? vm? , vars/functions declared outside vm var isdataloaded
? i'd appreciate insight this. right way it? many thanks.
edit: ok, found out how use controlleras syntax this. code in child controller this:
function childcontroller($controller, $scope, myfactory) { $controller('parentcontroller vm', {$scope: $scope}); var vm = $scope.vm; var template = 'screen'; // ************** m n ************** myfactory.getresults(url, vm); }
but still need way recover regular var/functions inside parent controller. ideas? can done cleanly?
i recommend implement usual javascript's inheritance mechanism between 2 classes. @ childcontroller constructor execute parentcontroller constructor , pass injected parameters (without using $controller
service). created simple example (very far logic consider patten). have 2 controllers: parentcontroller , childcontroller, inherited first one. used childcontroller $scope
, $interval
, custom service name "myservice" (all of them needed example). can see used methods , fields parent , child controllers. logic of app simple: can add new items collection (by means of parentcontroller) , remove them(by means of childcontroller) logging.
at case recommend use childcontroller ctrl data binding instead of $scope
, because more in line inheritance paradigm (we inherite controllers(ctrl) not $scope
).
p.s. if going use inheritance recommend use typescript - gives simple , flexible solution of problem in c# style.
controllers.js
function parentcontroller(myservice, $scope, $interval) { this.newone={}; this.lastacivity={}; this.$interval = $interval; this.items = myservice(); } parentcontroller.prototype.log = function(item){ var self = this; this.$interval(function(){ console.log(item); self.lastacivity = item; }, 100, 1); } parentcontroller.prototype.addnew = function (name, age) { var newitem = { name: this.newone.name, age: this.newone.age } this.items.push(newitem); this.log(newitem); } function childcontroller(myservice, $scope, $interval) { //transfering myservice, $scope, $interval childcontroller parentcontroller constructor, //also can pass want: $http, $location etc. parentcontroller.apply(this, [myservice, $scope, $interval]); } childcontroller.prototype = object.create(parentcontroller.prototype) //your childcontroller's own methods childcontroller.prototype.remove = function (item) { this.items.splice(this.items.indexof(item), 1); this.log(item); }
script.js
(function(angular) { 'use strict'; angular.module('scopeexample', []).factory('myservice', function() { var items = [ {name:"mike",age:21}, {name:"kate",age:22}, {name:"tom",age:11} ]; return function(){ return items; } }).controller('childcontroller', ['myservice', '$scope', '$interval', childcontroller]); })(window.angular);
html
<body ng-app="scopeexample"> <div ng-controller="childcontroller ctrl"> <label>name</label> <input type='text' ng-model='ctrl.newone.name'/> <label>age</label> <input type='text' ng-model='ctrl.newone.age'/> <input type='button' value='add' ng-click='ctrl.addnew()' ng-disabled="!(ctrl.newone.name && ctrl.newone.age)"/> <br> <br> <table> <thead> <tr> <th>name</th> <th>age</th> <th></th> </tr> </thead> <tbody> <tr ng-repeat="item in ctrl.items"> <td>{{item.name}}</td> <td>{{item.age}}</td> <td> <input type='button' value='x' ng-click='ctrl.remove(item)'/> </td> </tr> </tbody> </table> <p>{{ctrl.lastacivity | json}}</p> </div> </body>
Comments
Post a Comment