2014-02-17 9 views
0

Что я хочу сделать, это натолкнуть объект на массив, привязанный к html, привязанный к angularjs, а затем сделать функцию щелчка на новом созданном элементе. код как этот

$scope.fruits = {"orange", "plum", "cherry"}; 
$scope.add = function() { 
    $scope.fruits.push("apple"); 
    //this would add an element to the html, then I want to click on the element 
    $('#fruits').children.eq(-1).click();//click the last element (which has just been created) 
} 

HTML, это как:

<div id="fruits"> 
    <div ng-repeat="fruit in fruits"></div> 
</div> 

Проблема заключается в том, когда объект помещается в модель, угловатый бы сделать что-то вроде $ объема $ применяются(). для динамического обновления html. Если я нажимаю последний элемент с .children(). Eq (-1) .click(), он не будет ждать после создания нового элемента, то, что он на самом деле нажимает, является div «cherry». .

Я пытался позвонить $ объем $ применяется() до щелчка(), она работает, но я получил сообщение об ошибке:

$apply already in progress 

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

+0

Не могли бы вы подробнее рассказать о том, что делает действие click? Я думаю, что было бы лучше искать альтернативный способ достижения конечной цели, не используя click(). –

+0

Право. У меня есть аккордеон (бутстрап) и кнопка, чтобы добавить новую панель на аккордеон. Я хочу, чтобы открыть новую панель и закрыть другие, когда вы нажимаете кнопку «Создать». –

+0

Возможно, это не совсем то, что вы ищете, но вот пример, который будет расширять последнюю панель в гармонике при повторной визуализации (например, когда вы добавляете новую панель в конец). http://plnkr.co/edit/fSevqkgzQ9WB7fqerdja?p=info Если у вас есть дополнительная информация о ваших требованиях (например, какая панель будет первоначально расширена, новые панели всегда будут добавлены до конца), тогда, возможно, я смогу помочь с более конкретное решение. –

ответ

0

Когда вы добавляете в область $ scope, вы находитесь внутри цикла дайджеста, и DOM не будет скомпилирован и обновлен до тех пор, пока эти циклы не будут завершены - в основном в вашем приложении $ scope вы меняете массив, но в этот момент рендеринг DOM все еще имеет предыдущие элементы. Как только он выйдет из цикла, наблюдатели от репитера будут стрелять и отображать новый элемент DOM, но вы уже покинули свой контроллер.

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

setTimeout(function() { 
    $('#fruits').children().eq(-1).click(); 
}, 0); 

Вот рабочая скрипку: http://jsfiddle.net/jeremylikness/bWeQL/

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

+0

Ну, это решает и помогает мне узнать больше о угловом применении/дайджест-петле. Я не уверен, как написать директиву для манипуляции переменной is-open, поскольку директива аккордеона записывается угловым-ui. Спасибо –

+0

Я бы использовал '$ timeout' вместо' setTimeout', чтобы оставаться в угловом мире, когда вызывается обратный вызов таймера. Здесь вы просто запускаете клик, используя jQuery, но в реальной жизни вы можете обновить область действия и сделать это за пределами углового мира вызовет проблемы с обновлением пользовательского интерфейса. – Sylvain

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