2015-06-15 6 views
3

Я работаю над проектом с открытым исходным кодом для директивы (по-прежнему WIP). Когда вы смотрите на компоненты, такие как Angular Grid или UI Grid все они описывают свои столбцы и атрибуты объекта в родительском контроллере, как:Угловая выразительная директива дизайна

$scope.gridOptions = { 
    enableSorting: true, 
    enableCellEditOnFocus: true, 
    columnDefs: [ 
    { name: 'field1', enableSorting: false, enableCellEdit: false }, 
    { name: 'field2' }, 
    { name: 'field3', visible: false } 
    ] 
}; 

, который прекрасно работает, однако, я не думаю, что это действительно «угловой путь ». Он больше похож на виджет jQuery. Если вы посмотрите на проекты, подобные Angular Material, они гораздо более выразительны в шаблоне HTML и объекте.

Для моей реализации я изначально хотел сделать ее очень выразительной и разоблачить каждую из внутренних директив, которые я использую, однако это закончилось беспорядком, чтобы просто создать базовую таблицу. Так что я сделал некоторые исследования на другие структуры и обнаружили, что срабатывают имел хорошую архитектуру, где вы просто определить столбцы, как:

React.render(
    <Table 
    rowHeight={50} 
    rowGetter={rowGetter} 
    rowsCount={rows.length} 
    width={5000} 
    height={5000} 
    headerHeight={50}> 
    <Column 
     label="Col 1" 
     width={3000} 
     dataKey={0} 
    /> 
    <Column 
     label="Col 2" 
     width={2000} 
     dataKey={1} 
    /> 
    </Table>, 
    document.getElementById('example') 
); 

Я чувствую в любви с этим подходом, его простой и выразительный все в то же время. 90% времени, когда вы хотите настроить шаблон столбца в любом случае. Таким образом, вместо этого:

$scope.gridOptions = { 
    enableFiltering: true, 
    rowTemplate: rowTemplate(), 
    data: 'data', 
    columnDefs: [ 
     { name: 'name' }, 
     { name: 'gender' }, 
     { name: 'company' }, 
     { name: 'widgets' }, 
     { 
     name: 'cumulativeWidgets', 
     field: 'widgets', 
     cellTemplate: '<div class="ui-grid-cell-contents" title="TOOLTIP">{{grid.appScope.cumulative(grid, row)}}</div>' 
      } 
    ] 
}; 

с шаблоном клетки, вы могли бы сделать что-то вроде этого:

<dt options="options" rows="data" class="material"> 
    <Column name="name" width="300"></Column> 
    <Column name="Gender"> 
    <strong>{{value}}</strong> 
    </Column> 
    <Column name="Company"></Column> 
</dt> 

уведомления, как я взял Реагировать концепцию и парную его с более угловатыми концепциями, где я бы включил возможность иметь шаблон внутри столбца.

Хорошо, теперь проблема. Мне нужны столбцы в init, но не после этого. Я хочу заменить его фактической таблицей. Проблема в том, что я никогда не смогу получить этот HTML-код, когда мне это нужно.

Так on this line я пытался сделать что-то вроде:

compile: function(tElem, tAttrs){ 
    var tags = z.getElementsByTagName('column'); 
    console.log(tags) // equals = [] 
    return { 
     pre: function($scope, $elm, $attrs, ctrl){ 
     } 
    }; 
} 

но колонны никогда там сезам позже, когда я пытаюсь transclude их (на самом деле не то, что я хочу сделать). Мне нужен способ получить их до того, как контроллер будет инициализирован, и шаблон заменит внутреннее содержимое. Вот plunkr!

Кроме того, поскольку моя директива ограничена (что я хочу сделать по основным причинам), у меня нет возможности получить доступ к родительской области для компиляции внутреннего шаблона с внешним содержимым.

Кроме того, любые предложения/мысли по этой парадигме дизайна? Благодаря!

+0

Не знаю, как реагировать, но интересный подход. – YOU

+0

Во-первых, действительно отличный подход и, наконец, кто-то пытается реально использовать угловую пользовательскую директиву. Однако не могли бы вы дать образец в plunkr? Это может помочь вам решить проблему. – Okazari

+0

@You - ya, я просто сравнивал реакцию «дизайн», а не фактическую реакцию выполнения/etc – amcdnl

ответ

1

Я только нашел странный способ достичь желаемого.

Прежде чем кто-нибудь даст лучшее решение, вот моя работа в этом plunker.

Добавление $transclude службы к контроллеру и transclude:'element' директиве

app.directive("simple", function(){ 
    return { 
     restrict: "EA", 
     replace:true, 
     transclude:'element', 
     template:"<div>table</div>", 
     compile: function(element, attributes, transclude){ 
      var tags = element[0].getElementsByTagName('column'); 
      console.log("compile", tags); 
      console.log("transclude", transclude); 
      return { 
       pre: function(scope, element, attributes, controller, transcludeFn){ 
        var tags = element[0].getElementsByTagName('column'); 
        console.log("pre", tags); 
       }, 
       post: function(scope, element, attributes, controller, transcludeFn){ 
        var tags = element[0].getElementsByTagName('column'); 
        console.log("post", tags); 
       } 
      } 
     }, 
     controller: function($scope, $element, $transclude){ 
       $transclude(function(clone,scope){ 
       /* for demo am converting to html string*/ 
       console.log("From controller",angular.element(clone).find('column')); 
       }); 
     } 
    }; 
}); 

Я проверил некоторые другие вещи. Но я могу получить столбец только с этим и только в контроллер.

+0

Мне интересно, как $ transclude будет работать с классом ES6;) – amcdnl

+0

@amcdnl Означает ли это, что он не может работать в вашем случае? (я мало знаю о классах ES6). Если это не сработает для вас, я удалю это и скачу другой ответ :) – Okazari

+0

Я не уверен, оставь сейчас. необходимо проверить. – amcdnl

3

Попробуйте использовать template как function, который возвращает фактическую строку шаблона.Первым параметром является исходный html:

var tags; 
return { 
    template: function(element) { 
     tags = element[0].getElementsByTagName('column'); 
     return "<div>table</div>"  
    }, 
    compile: ... 
} 
+0

Это хорошая идея! хочу, чтобы у меня был доступ к области видимости: S – amcdnl

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