0

Просто устремив голову вокруг Углового - не понимая нескольких понятий, поскольку я родом из школы мышления.Вложенные директивы/контроллеры в угловом поле

Для начала я выбрал случайный проект: карточную игру.

Предположим, что я хотел определить контроллер hand и контроллер card. Для простоты я хочу иметь их в качестве директив.

Вот директива карты:

app.directive('card', function(){ 

    return { 
     restrict:'E', 
     templateUrl:'card.html', 
     controller:function($scope){ 
      this.suit = 'clubs'; 
      this.rank = 'a'; 
      this.suitClass = function(){ 
       return this.suit + '-' + this.rank; 
      } 
     }, 
     controllerAs:'card' 
    }; 
}); 

А вот рука директива:

app.directive('hand', function(){ 

    return { 
     restrict:'E', 
     template:'hand.html', 
     controller:function($scope){ 
      this.cards = [ 
       {suit:'clubs', rank:'a'}, 
       {suit:'spades', rank:'10'}, 
       {suit:'hearts', rank:'2'}, 
       {suit:'diamonds', rank:'k'} 
      ]; 
     }, 
     controllerAs:'hand' 
    } 
}); 

С following plunker, я ожидал, чтобы иметь возможность просто упасть в <hand></hand> элемент и есть угловые делают всю работу для меня. В моем сознании глаз должны быть карточки, представляющие различные костюмы, вложенные в директиву <hand>. Что мне не хватает? В настоящее время, как вы можете сказать в плункере, вложенный контроллер/директива не создает экземпляр представления правильно.

Я думаю о слишком большом пути MVC? ООП преследует меня? Или угловато просто плохо спроектировано?

+0

[Завершился ваш плункер] (http://plnkr.co/edit/b3PcWwu3diyAvMaPakpi?p=preview) с некоторыми незначительными изменениями, «карта» от контроллераА и «карта» из повторного вида, разбившегося в этой области. Это далеко не идеальное решение, но хотелось сделать как можно меньше изменений, чтобы вы могли видеть, как это можно настроить для работы. – JimL

+0

@ JimL Спасибо за плункер. Так ли я прав, предполагая, что между двумя представлениями нет реальной взаимосвязи, согласитесь, что свойства из 'hand' получаются композиционно добавленными к новой« карточке »через пространство имен $ scope? – shennan

ответ

0

Я не 100% уверен, что я понимаю ваш вопрос, но я думаю, что это лучший способ, чтобы написать это:

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

app.directive('card', function(){ 

    return { 
     restrict:'E', 
     templateUrl:'card.html', 
     replace: true, 
     link: function ($scope, element, attrs){ 
      $scope.suit = 'clubs'; 
      $scope.rank = 'a'; 
      $scope.suitClass = function(){ 
       return this.suit + '-' + this.rank; 
      } 
     } 
    }; 
}); 

app.directive('hand', function($compile){ 

    return { 
     restrict:'E', 
     templateUrl:'hand.html', 
     link:function($scope, element, attrs){ 
      $scope.cards = [ 
       {suit:'clubs', rank:'a'}, 
       {suit:'spades', rank:'10'}, 
       {suit:'hearts', rank:'2'}, 
       {suit:'diamonds', rank:'k'} 
      ]; 
     } 
    } 
}); 

И HTML может быть что-то вроде этих: (рука шаблон директивы)

<div> 
    <card ng-repeat="card in cards"></card> 
</div> 

И (шаблон директива карты)

<div ng-class="card.suitClass()"> 
{{ suit }} 
</div> 
+0

Спасибо за ваш ответ. Но не могли бы вы объяснить немного больше о том, что «ссылка» надеется достичь здесь? Я [воссоздал ваш код в plunker] (http://plnkr.co/edit/LEowBcGigWbGjB0aOFqI?p=preview), и он, кажется, заменяет элемент 'card' с' div' и не может вызвать 'suitClass' для соответствующего стиля. – shennan

0

Поясню проблему, перейдя сверху вниз через порядок элементов/объектов, которые будут называться: директива

руки:

директива является нормально до сих пор. Но параметр $ compile и параметр $ scope не используются, и их следует удалить. Чтобы быть более ясным, я применил это к переменной, но это не меняет поведение приложения.

app.directive('hand', function(){ 

    return { 
    restrict:'E', 
    templateUrl:'hand.html', 
    controller:function() { 
     var hand = this; 
     hand.cards = [ 
     {suit:'clubs', rank:'a'}, 
     {suit:'spades', rank:'10'}, 
     {suit:'hearts', rank:'2'}, 
     {suit:'diamonds', rank:'k'} 
     ]; 
    }, 
    controllerAs:'hand' 
    } 
}); 

hand.html:

Вы не прошли текущую карточку нг-повтора в директиве карты. Таким образом, вы создаете только шаблоны карт, умноженные на количество карт, но никогда не используя фактические значения.

я удалил устаревший Div тег и повысил hand.html к этому:

<card ng-repeat="card in hand.cards" card-model="card"></card> 

Таким образом, я получаю все карты с точкой зрения руки в директиве карты.

карта директива:

Сначала я удалить переменную $ области действия, потому что он никогда не используется и не будет использоваться здесь.

Эта функция довольно неполна. По крайней мере, отсутствуют значения карт, которые вы хотите использовать. Но главная проблема здесь заключается в том, что контекст этого связан с вызывающим. Чтобы быть более точным, вы используете это внутри функции suitClass, но вы хотите использовать значения костюма и ранга контроллера. это не указывает на функцию контроллера, а на вновь созданную функцию suitClass, которая не знает ни одного из этих значений. Для этой проблемы вы должны ввести переменную, содержащую контекст и доступ к таким значениям. И я добавляю переменную cardModel области, которая привязана к атрибуту element для получения желаемых значений. И я добавляю bindToController: истинный доступ к переданному в модели, как card.cardModel вместо чистого cardModel:

app.directive('card', function(){ 
    return { 
    restrict:'E', 
    scope: { 
     cardModel: '=' 
    }, 
    templateUrl:'card.html', 
    controller:function(){ 
     var card = this; 
     console.log(card.cardModel) 
     card.suitClass = function(){ 
      return card.cardModel.suit + '-' + card.cardModel.rank; 
     } 
    }, 
    controllerAs:'card', 
    bindToController: true 
    }; 
}); 

card.html:

Эта точка зрения хорошо. Я только применил свои изменения:

<div ng-class="card.suitClass()">{{ card.cardModel.rank }}</div> 

Надеюсь, это по-прежнему полезно для всех.

Смежные вопросы