Odore di codice nella direttiva personalizzata AngularJS

2

Nel codice seguente.

<!DOCTYPE html>
<html ng-app="app10" ng-cloak>
    <head>
        <title>Custom directives</title>
        <style>
            [ng\:cloak], [ng-cloak], .ng-cloak{
                display: none;
            }
        </style>
    </head>
    <body>

        <div ng-controller="mainCtrl as o">
            <div  bb-player-list="bbPlayers" array-item="name | uppercase" ng-model="o"> 

            </div>
        </div>

        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script><scripttype="text/javascript" src="js/exam10.js"></script>
    </body>
</html>
var app10 = angular.module("app10", []);


app10.directive("bbPlayerList", DirectiveFunction);

function DirectiveFunction(){
    return function(scope, element, attrs){
            var data  = "";
            if(attrs["ngModel"] === "")
                data = scope[attrs["bbPlayerList"]];
            else
                data = scope[attrs["ngModel"]][attrs["bbPlayerList"]];

    }
}

app10.controller("mainCtrl", MainController);

function MainController(){
    this.bbPlayers = [
        {name: "Barry Bonds", avg: 0.298, hr: 762, obp: 0.444},
        {name: "Hank Aaron", avg: 0.305, hr: 755, obp: 0.374},
        {name: "Babe Ruth", avg: 0.342, hr: 714, obp: 0.474},
        {name: "Ted Williams", avg: 0.344, hr: 521, obp: 0.482}
    ];


}

In DirectiveFunction , c'è un odore di codice nel recuperare i dati usando ngModel ,

    var data  = "";
    if(attrs["ngModel"] === "")
        data = scope[attrs["bbPlayerList"]];
    else
        data = scope[attrs["ngModel"]][attrs["bbPlayerList"]];

Il motivo per aggiungere questo codice è l'odore,

se il controller è istanziato come mainCtrl as o allora ngModel sarebbe "o" altrimenti ngModel sarà "" . Questo attributo ngModel deciderà come accedere a bbPlayers in DirectiveFunction ?

Posso evitare questo odore di codice in DirectiveFunction ?

In che modo DirectiveFunction viene immune, il modo in cui mainCtrl viene istanziato?

    
posta overexchange 24.03.2016 - 17:03
fonte

1 risposta

1

Dovresti considerare require -ing il ngModel controller (e MainController , se necessario) all'interno della tua definizione direttiva invece di esaminare attrs all'interno della funzione link :

function DirectiveFunction(){
  return {
    require: [ '^ngController', '?ngModel' ],
    link: (scope, element, attrs, controllers) => {
      const [ MainController, ngModel ] = controllers;

      data = main.bbPlayers;
    }
  };
}

Sembra che tu stia cercando di condividere i dati tra i controller, tuttavia, cosa che è meglio fare attraverso un servizio con nome condiviso. Considera invece:

angular.module('app10')
  .factory('Players', function(){ // injectable, if you need it...
    return [
      {name: "Barry Bonds", avg: 0.298, hr: 762, obp: 0.444},
      {name: "Hank Aaron", avg: 0.305, hr: 755, obp: 0.374},
      {name: "Babe Ruth", avg: 0.342, hr: 714, obp: 0.474},
      {name: "Ted Williams", avg: 0.344, hr: 521, obp: 0.482}
    ];
  })
  .directive('bbPlayerList', function(){ // also injectable...
    return {
      controller: function(Players){ // injectable again...
        // Do stuff with 'Players' if you need to...
      }
    }
  });

Se devi recuperare i dati da un server e memorizzare nella cache i risultati, puoi inserire quella logica nell'impostazione di Players o esporre un metodo che faccia lo stesso:

angular.module('app10')
  .factory('Players', function(){ // injectable again...
    return {
      all: () => [
        {name: "Barry Bonds", avg: 0.298, hr: 762, obp: 0.444},
        {name: "Hank Aaron", avg: 0.305, hr: 755, obp: 0.374},
        {name: "Babe Ruth", avg: 0.342, hr: 714, obp: 0.474},
        {name: "Ted Williams", avg: 0.344, hr: 521, obp: 0.482}
      ]
    };
  });

Quindi chiama Players.all() all'interno di qualsiasi costruttore per ottenere tutti i giocatori. Puoi sostituire facilmente i dati fittizi con una chiamata a un endpoint con $http o $resource o Restangular.

    
risposta data 22.09.2016 - 16:42
fonte

Leggi altre domande sui tag