0

У меня проблема, когда вложенность прилагаемых директив работает некорректно. запрос-строка представляет собой директиву (с шаблоном HTML), и я хочу иметь следующую структуру DOMКак добавить директиву в Angular

желаемого результата

<query-row></query-row> 
<query-row></query-row> 
<query-row></query-row> 
etc... 

Но что я получаю это. Также смотрите скриншот

<query-row> 
    <query-row></query-row> 
    <query-row></query-row> 
    etc... 
</query-row> 

enter image description here

код Javascript. Как вы можете видеть здесь, в контроллере я создаю элемент с именем query-row, а затем добавляю его к предыдущей строке запроса ... но здесь моя логика ошибочна, потому что она не добавляется, а скорее вложенные в первую строку запроса.

angular.module('app', ['ngAnimate', 'ui.bootstrap']) 
    .controller('queryBuilderCtrl', ['$scope', '$compile', function($scope, $compile) { 

    $scope.add = function() { 
     var queryRow = angular.element(document.createElement('query-row')) 
     $compile(queryRow)($scope) 
     angular.element('query-row').append(queryRow) 
    } 
    }]) 
    .directive('queryBuilder', function() { 
    return { 
     restrict: 'E', 
     templateUrl: 'queryBuilderTemplate.html', 
     link: function(scope, elem, attrs) { 

     } 
    } 
    }).directive('queryRow', function() { 
    return { 
     restrict: 'EA', 
     templateUrl: 'queryRowTemplate.html', 
     link: function(scope, elem, attrs) { 

     } 
    } 
    }); 

Вот plnkr http://plnkr.co/edit/1WAgBCEbyk7Tz3fLKnnW

+2

.append' что объявление ding внутри, вы должны использовать '.after()' /'.before() '.., но также делать манипуляции с DOM с контроллера будет считаться плохим шаблоном. –

+2

Что касается лучших практик, вы не должны использовать. добавьте для добавления HTML на свою страницу. В идеале вы бы управляли представлениями вашего ребенка в повторителе, например ng-repeat или какой-либо другой директивой, тогда вы можете просто иметь переменную $ scope, которая содержит данные для правильного ввода в каждый элемент с петлями. Или в этом случае ваш queryBuilder должен содержать ретранслятор, который будет управлять строками запроса – SoluableNonagon

+0

@SoluableNonagon вы можете объяснить это в примере? Мне не очень нравится решение .append либо – user1142130

ответ

0

ответ на вопрос

Оказывается, что проблема здесь:

angular.element('query-row').append(queryRow) 

вероятно Вы имели в виду:

angular.element('query-row').last().after(queryRow) 

Редактировать - изменено на место queryRow элемент внутри элемента формы за комментарий @ PierreDuc. Это находит последний элемент <query-row>, а затем добавляет вновь созданный элемент queryRow после него.

лучшее решение

Но, честно говоря, это очень не, как я рекомендовал бы это делать. У вас есть контроллер вида (queryBuilderCtrl) ручка DOM-манипуляции. В крайних случаях вы должны это делать. Вероятно, вы должны создать объект модели массива в своем queryBuilderCtrl, а его шаблон использует ng-repeat для обработки создания/уничтожения DOM.

Plunker - http://plnkr.co/edit/k4PUNfeRdeGsxEdruEZi?p=preview

+0

, которое разместит его вне формы. Я полагаю, что это должно быть 'angular.element ('query-row'). Last(). After (queryRow)' – PierreDuc

+0

@jusopi, нет, я хочу, чтобы все строки помещались внутри формы, которая является частью запроса- строитель. Может быть несколько строк запроса внутри query-builder – user1142130

+0

использовать предложение PierreDuc, тогда я обновлю ответ – jusopi

0

Использование angular.element('query-row').last().after(queryRow)

Это работает, потому что он будет первым выбрать все query-row элементы. С помощью функции last() вы получите последнюю (очевидно). С after(queryRow), вы поместите queryRow после последнего элемента query-row

Как @jusopi заявил, манипуляция DOM, однако, должна быть сведена к минимуму в контроллерах

0

Вот ваш пример исправлено: http://plnkr.co/edit/DPy8YoaGh1mAAJpFrWE7

Я добавил новый <div> с классом query-row-wrapper внутри queryBuilderTemplate.html, поэтому каждый новый скомпилированный query-row прилагается к этой оболочке.

В результате HTML выглядит так, как ожидалось.

0

Shoot для не- .append решения

http://plnkr.co/edit/i4S3K4JjcTPXkTLT9eOq?p=preview

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

app.controller('myCtrl', ['$scope', function($scope){ 

    $scope.rows = [{data: 'something'}]; 
    $scope.add = function() { 
    $scope.rows.push({data: 'data1'}); // whatever data goes into a row 
    } 


}]); 

app.directive('queryBuilder', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     rows: "=" 
    }, 
    templateUrl: 'queryBuilderTemplate.html', 
    link: function(scope, elem, attrs) { 
     // do something here? 
     console.log(scope.rows); 
    } 
    } 
}).directive('queryRow', function() { 
    return { 
    restrict: 'EA', 
    scope: { 
     data: "=" 
    }, 
    templateUrl: 'queryRowTemplate.html', 
    link: function(scope, elem, attrs) { 
     // process data in some way? 
     console.log(scope.data) 
    } 
    } 
}); 

queryBuilderTemplate.html

<div class="queryBuilder"> 
    <query-row ng-repeat='row in rows' data='row.data'></query-row> 
</div> 

queryRowTemplate.html

Test {{data}} 
Смежные вопросы