Я разрабатывал todo-приложение с jQuery, но хотел бы перейти на Angular.
Существует поле ввода для добавления нового элемента, но как только что-либо вводится в этот ввод, нажатие клавиши и последующие за ним эффективно перемещаются к новому элементу среди группы существующих элементов. Это означает, что текстовое поле ввода нового элемента всегда остается пустым. Лучше показать, чем объяснять:
http://jsfiddle.net/29Z3U/4/ (многие детали удалены, но аспект приложение, о котором я говорю, демонстрируется).
<h1>Song List</h1>
<form id="songs">
<ul id="sortable_songs"></ul>
</form>
<ul id="new_song">
<script id="song_form_template" type="text/x-handlebars-template">
<li class="song" id="{{song_id}}">
<input type="text" placeholder="enter song" autofocus />
</li>
</script>
</ul>
Немного jQuery:
var template = Handlebars.compile($('#song_form_template').html()),
counter = (function(){var i=0; return function(){return ++i};})(),
cloneNewSong = function(){
var count = counter(),
templateVals = {song_id: 'song_' + count};
$('ul#new_song').append(template(templateVals));
},
addSong = function(event){
//exclude certain keys here
cloneNewSong();
container = $(event.target).closest('li.song');
container.appendTo('ul#sortable_songs');
$(event.target)
.removeAttr('placeholder')
.focus(); //what I just typed disappears without this! why?
};
$('ul#new_song').on('keypress', 'input', addSong);
cloneNewSong();
Обратите внимание, что текстовое поле ввода нового элемента всегда остается пустым, а фокус ведет себя так, как должен, поэтому вы можете продолжать печатать без перерыва.
Код приложения становится длинным, и я даже еще не пытался отобразить существующий список песен, полученный из JSON. Конечно, в Angular это легко сделать с помощью ngRepeat. Однако моя попытка создать версию для Angular не работает: http://plnkr.co/edit/xsGRiHFzfsVE7qRxgY8d?p=preview
<!DOCTYPE html>
<html ng-app="songListApp">
<head>
<script src="//code.angularjs.org/1.2.7/angular.js"></script>
<link href="style.css" rel="stylesheet" />
<script src="script.js"></script>
</head>
<body ng-controller="songListController">
<h1>Song List</h1>
<ul id="songs">
<li ng-repeat="song in songs">
<input type="text" ng-model="song.song_name" />
</li>
</ul>
<form>
<input
ng-keypress="newSong(new_song)"
ng-model="new_song.title"
placeholder="enter song" autofocus
/>
</form>
</body>
</html>
JS:
var myapp = angular.module('songListApp', []);
myapp.controller('songListController', function($scope){
songs = [
{"song_name":"song 1","more_info":""},
{"song_name":"song 2","more_info":""},
{"song_name":"song 3","more_info":""}
];
$scope.songs = songs;
$scope.newSong = function(new_song){
var song = {"song_name": new_song.title, "more_info":""};
songs.push(song);
new_song.title = '';
};
});
Еще до того, как заняться проблемой управления фокусом, я замечаю, что обновление модели Angular всегда отстает на одно нажатие клавиши. Я предполагаю, что это связано с тем, что событие нажатия клавиши происходит перед символом вставляется в DOM.
Я понимаю, что переключение с нажатия клавиши на нажатие клавиши изменит ситуацию, но первоначальный дизайн был основан на отзывчивости нажатия клавиши.
Я попробовал пользовательскую директиву для привязки к событию ввода, но все работает не так, как я надеялся: http://plnkr.co/edit/yjdbG6HcS3ApMo1T290r?p=preview
Я заметил, что первый пример кода на angularjs.org (базовая привязка без контроллера), похоже, не страдает от проблемы, с которой я столкнулся: модель примера обновляется до выпуска ключа.