Вопрос

I'm migrating from Backbone to Angular, and am trying to figure out a good pattern for adding methods to objects in the Angular world. Backbone wasn't opinionated about much, but they did standardize on extending objects like this:

Grid = Backbone.View.Extend({
  initialize: function(){
    grid = new Slick.Grid(el, [], [], {})
    grid.onSort.subscribe(this.onClick.bind(this)) // .onSort is a SlickGrid event
  },
  onSort: function(){}
})

This structure made this part of Backbone very predictable across projects and developers. What's the way to do this in Angular? I've come up with three alternatives for adding methods to directives and am not sure which if any is the Angular Way. This is an example creating a directive to expose SlickGrid to an Angular application, but the answer could and should apply the addition of static, instance-attached, or prototype-attached methods to angular directives, controllers, and services generally. If there's a different answer for each Angular object type, that's cool too.

Here are some approaches I've considered:

Leverage private static methods from parent closure:

var _onSort = function() {};
angular.module('app').directive('grid', function() {
  return {
    link: function($scope, el) {
          grid = new Slick.Grid(el, [], [], {})
          grid.onSort.subscribe _onSort.bind(this)
    }
  };
});

Use methods on the link prototype

gridLink = function($scope, el) {
      grid = new Slick.Grid(el, [], [], {})
      grid.onSort.subscribe(this.onSort.bind(this))
};
gridLink.prototype = {
  onSort: function() {}
};
angular.module('app').directive('grid', function() {
  return {
    link: gridLink // This might not work, since there's not an instance?
  };
});

Use local closure from the link method (applied to a service or directive this would probably mean the constructor)

angular.module('app').directive('griddle', function() {
  return {
    link: function($scope, el) {
      var onSort = function() {};
          grid = new Slick.Grid(el, [], [], {})
          grid.onSort.subscribe(onSort.bind(this));
    }
  };
});
Это было полезно?

Решение 2

Paraphrased from @jelbourn in this slideshow, there are 3 ways:

  1. Inheritance
  2. Mixins
  3. Object Composition

Pages 14, 15, and 16 in the slides talk about these options in more depth.

What he ends up recommending (if I understand correctly) is using #3 Object Composition most of the time and treating controllers and services like classes:

app.ZipCodeFieldController = function(){}
app.ZipCodeFieldController.prototype.autocomplete = function() {}

You can then mix in prototypal controllers:

app.PaymentFormController = function($scope, ZipCodeFieldController, $controller) {
  $scope.zipCode = $controller(ZipCodeFieldController)
}

And use them in the template neatly:

<input type="text" name="zip" ng-change="zipCode.autocomplete" ng-model="zip" />

He also has a bit about very granular modules on slide 24 that is interesting.

Also good: https://github.com/yeoman/generator-angular/issues/109

There's a segment on object organization at the ng-conf talk on writing massive Angular apps at 15:14 in the video:

Другие советы

You are missing the built in directives/methods already provided by angular which is the best place to start.

Go through list of ng directives in left nav of API...will see many event oriented ones like ngClick, ngChange, ngMousemove etc....display directives like ngShow, ngClass ... properties like ngChecked, ngSrc and an important one to bind model to input fields, ngModel. Most of these have demos linked to plunker or jsfiddle within the docs

To use in markup

<a ng-click="doSomething()">Do Something</a>

Then in controller or link of directive

$scope.doSomething=function(){
   console.log('I did it!');
   $scope.message='I did it!';
}

Now any scope properties you manipulate within the event handler will automatically be watched by angular, and any views affected will be automatically updated.

Highly recommend spending the time to go through tutorial on docs site step by step!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top