Domanda Come specificare il modello in una direttiva ngInclude in AngularJS?


Vorrei utilizzare lo stesso modello HTML in 3 posizioni, solo ogni volta con un modello diverso. So che posso accedere alle variabili dal modello, ma i nomi saranno diversi.

C'è un modo per passare un modello a ngInclude?

Questo è ciò che mi piacerebbe ottenere, ovviamente l'attributo variabile add non funziona ora. Quindi nel mio modello incluso, vorrei accedere a detailsObject e alle sue proprietà.

<pane title="{{projectSummary.ProjectResults.DisplayName}}">
    <h2>{{projectSummary.ProjectResults.DisplayName}}</h2>
    <ng-include src="'Partials/SummaryDetails.html'" init-variable="{'detailsObject': projectSummary.ProjectResults}"></ng-include>
</pane>

<pane  title="Documents" header="true"></pane>

<pane ng-repeat="document in projectSummary.DocumentResults" title="{{document.DisplayName}}">
    <h2>{{document.DisplayName}}</h2>
    <ng-include src="'Partials/SummaryDetails.html'" add-variable="{'detailsObject': document}"></ng-include>
</pane>

<pane ng-repeat="header in [1]" title="Languages" header="true"></pane>

<pane ng-repeat="language in projectSummary.ResultsByLanguagePairs" title="{{language.DisplayName}}">
    <h2>{{document.DisplayName}}</h2>
    <ng-include src="'Partials/SummaryDetails.html'" add-variable="{'detailsObject': language}"></ng-include>
</pane>

Se ho preso un cattivo approccio con l'uso di ng-include, c'è qualcos'altro che dovrei provare?


44
2017-11-16 19:16


origine


risposte:


NOTA: questa non è la mia risposta originale ma questo è come lo farei dopo aver usato l'angolare per un po '.

Vorrei creare una direttiva con il modello html come il markup che passa nei dati dinamici alla direttiva come visto in questo violino.

Passi / note per questo esempio:

  1. Definire una direttiva con markup in templateUrl e attributo (s) utilizzato per passare i dati nella direttiva (denominato type in questo esempio).
  2. Utilizzare i dati della direttiva nel modello (denominato type in questo esempio).
  3. Quando si utilizza la direttiva nel markup, assicurarsi di passare i dati dall'ambito del controller alla direttiva (<address-form type="billing"></address-form> (dove la fatturazione sta accedendo a un oggetto sull'ambito del controllore).
  4. Si noti che quando si definisce una direttiva il nome è camel cased ma quando viene utilizzato nel markup è delimitato in minuscolo (cioè è denominato addressForm nel js ma address-form nell'html). Maggiori informazioni su questo possono essere trovate nei documenti angolari Qui.

Ecco il js:

var myApp = angular.module('myApp',[]);

angular.module('myApp').directive('addressForm', function() {
    return {
        restrict: 'E',
        templateUrl: 'partials/addressform.html', // markup for template
        scope: {
            type: '=' // allows data to be passed into directive from controller scope
        }
    };
});

angular.module('myApp').controller('MyCtrl', function($scope) {
    // sample objects in the controller scope that gets passed to the directive
    $scope.billing = { type: 'billing type', value: 'abc' };
    $scope.delivery = { type: 'delivery type', value: 'def' };
});

Con markup:

<div ng-controller="MyCtrl">
    <address-form type="billing"></address-form>
    <address-form type="delivery"></address-form>
</div>

RISPOSTA ORIGINALE (che è completamente diversa dall'utilizzo di una direttiva BTW).

Nota: il violino dalla mia risposta originale qui sotto non sembra funzionare più a causa di un errore (ma tenerlo qui nel caso sia ancora utile)

C'è stata una discussione su questo nel gruppo Google che puoi vederlo qui.

Sembra che questa funzionalità non sia supportata immediatamente, ma è possibile utilizzare la patch di Brice come descritto in questo post.

Ecco il codice di esempio dal suo jsfiddle:

<script id="partials/addressform.html" type="text/ng-template">
    partial of type {{type}}<br>
</script>

<div ng-controller="MyCtrl">
  <ng-include src="'partials/addressform.html'" onInclude="type='billing'"></ng-include>
  <ng-include src="'partials/addressform.html'" onLoad="type='delivery'"></ng-include>
</div>

20
2017-11-16 19:31



C'è una soluzione piuttosto semplice, anche se devo ammettere che non è ciò che raccomanderebbe Misko. Ma se creare una direttiva è eccessivo per te e ottenere la patch di Brice non è fattibile, quanto segue ti aiuterà.

<div ng-repeat="name in ['A']" ng-include="'partial.html'"></div>
<div ng-repeat="name in ['B']" ng-include="'partial.html'"></div>

<script type="text/ng-template" id="partial.html">
   <div>{{ name }}</div>
</script>

È abbastanza evidente il motivo per cui funziona. Guarda un esempio qui: http://jsfiddle.net/Cndc6/4/


61
2017-12-17 16:13



C'è una spinta per risolvere questo problema ma sembra che sia morto: https://github.com/angular/angular.js/pull/1227

Senza modificare il codice sorgente Angolare questo risolverà il problema in modo riutilizzabile e non troppo hacky:

directive('newScope', function() {
    return {
        scope: true,
        priority: 450,
    };
});

E un esempio:

<div new-scope ng-init="myVar = 'one instance'" ng-include="'template.html'"></div>
<div new-scope ng-init="myVar = 'another instance'" ng-include="'template.html'"></div>

Ecco un Plunker di esso in azione: http://plnkr.co/edit/El8bIm8ta97MNRglfl3n


14
2018-01-23 17:58



<div new-scope="myVar = 'one instance'" ng-include="'template.html'"></div>

directive('newScope', function () {
    return {
        scope: true,
        priority: 450,
        compile: function () {
            return {
                pre: function (scope, element, attrs) {
                    scope.$eval(attrs.newScope);
                }
            };
        }
    };
});

Questa è una direttiva che combina new-scope a partire dal La risposta di John Culviner con il codice di Angular's ng-init.

Per completezza, questo è il 1.2 Angolare 1.2 sorgente di ng-init, puoi vedere che l'unica modifica nella direttiva new-scope è l'aggiunta di scope: true

{
  priority: 450,
  compile: function() {
    return {
      pre: function(scope, element, attrs) {
        scope.$eval(attrs.ngInit);
      }
    };
  }
}

6
2017-10-09 17:07



Soluzione rapida e rapida:

<div ng-init="details=document||language||projectSummary.ProjectResults">

5
2017-11-16 19:40



Ti sento! ng-include non è riutilizzabile perché ha accesso all'ambito globale. È un po 'strano

Ci dovrebbe essere un modo per impostare le variabili locali. Usando una nuova direttiva invece di ng-include è una soluzione più pulita.

L'utilizzo ideale è simile a:

<div ng-include-template="'Partials/SummaryDetails.html'" ng-include-variables="{ 'detailsObject': language }"></div>

La direttiva è:

.directive(
  'ngIncludeTemplate'
  () ->
    {
      templateUrl: (elem, attrs) -> attrs.ngIncludeTemplate
      restrict: 'A'
      scope: {
        'ngIncludeVariables': '&'
      }
      link: (scope, elem, attrs) ->
        vars = scope.ngIncludeVariables()
        for key, value of vars
          scope[key] = value
    }
)

Puoi vedere che la direttiva non usa l'ambito globale. Invece, legge l'oggetto da ng-include-variables e aggiunge quei membri al proprio ambito locale.

È pulito e generico.


1
2017-10-25 18:10