Pull to refresh

Comments 48

O.o() — мощное нововведение для web платформы, которое вы можете использовать уже сегодня.


Автор оригинала явно был слишком в восторге — иметь в виду — пожалуй, а ориентироваться на тех у кого Chrome 36 BETA было бы странно.

P.S. О_о выглядит аутентичнее :)
Мы надеемся, что это функциональность вскоре появится и в других браузерах, позволяя JavaScript фреймворкам получить некий выигрыш в производительности с новыми нативными возможностями объектов и наблюдением за ними. Помимо Chrome 36, эта функциональность так же будет доступно в ближайшем релизе Opera.

Я надеюсь, что эта функциональность появится в стабильных версиях браузеров только тогда, когда стандарт утверждён, но не раньше, а то будет как с web sockets
О мои глаза, они разрываются от слова «биндинг».
А по теме, это же просто замечательно, основной недостаток использования шаблонов MV* в JavaScript заключался в потере производительности по мере усложнения дерева DOM и увеличения количества одновременных привязок, но теперь, с нативной поддержкой открываются совершенно новые горизонты.
О, а как вы его называете?
Привязкой (как переводится на русский) или байндингом (как произносится в английском), зависит от аудитории :)
Вы правы, исправил. Спасибо за замечание!
А слово «дата» вас не смущает? Может уж сразу, «дэйта-байндинг»?
Мне глаза не рвет, но я называю это «байндингом» или, иногда, «привязкой».
По теме поддержу — очень многообещающая штука, надеюсь утвердят как можно скорее!
Да нет, MV* != dirty checking
Честно говоря, не представляю, как вообще Angular приобрел популярность с такой жуткой штукой под капотом.
Были похожие статьи(поверхностное овервью), но перевода именно этой небыло.
Господа переводчики, ну что за привычка игнорировать текст в комментариях? Поверьте, он ничем не отличается от текста переводимой статьи. Так почему же вы забиваете на его перевод? Что это за дурацкое табу? Особенно показателен случай в этой статье, когда после фразы «Обратите внимание на комментарии:» следует полотно кода с не переведёнными комментариями. А-а-а-а! Хочется биться головой об стену в таких случаях. Если уж переводите, делайте, пожалуйста, это полностью. Очень всех прошу.

P.S. Извините, но накипело.
Наверно дело привычки, но для меня дико выглядят комментарии на русском языке даже в примерах, не говоря уже о рабочем коде.

По теме — функционал конечно полезный. Привыкнув к привязке при работе с AngularJs приходится перестраиваться, когда не можешь ее использовать.
Простите, но именно в примерах их и надо переводить. Иначе зачем вообще нужны примеры? Вы же не будете их бездумно копипастить, не так ли? И никто же не заставляет вас писать по-русски в рабочем коде (хотя, если проект только для внутреннего использования, почему бы и нет). А здесь, простите, рассказывают о новой технологии, и эти самые комментарии являются продолжением текста статьи. Я уже привёл пример: фраза «Обратите внимание на комментарии:». Это значит, что автор считает, что в комментариях описываются некоторые нюансы, которые при переводе оказались безвозвратно утерянными.
// Наблюдаем за thingy(простите, язык не повернется писать «наблюдаем за рюшечками»)

Один из примеров когда переводить комментарии не лучшая идея. Тогда не плохо бы переменные транслитерировать. Кстати изображения без перевода вас не смущают?
Ну, я все-таки согласен с Mingun по поводу перевода комментариев. Разумеется, в жизни такого делать не стоит, но ведь это обычный обзор, и чем понятнее — тем лучше. Было бы неплохо переводить и изображения (например, на схемах), но это, может быть, где-нибудь в следующих переводах.
Кстати изображения без перевода вас не смущают?

Знаете, требовать от переводчика еще и перевода изображений — даже для меня это чересчур :) Что впрочем, не отменяет того факта, что если это будет сделано, то это будет просто о*утельно здорово! Всё-таки перерисовка изображений не каждому под силу, объём работ не сравнимый.
Полностью переводить комментарии — дело нелегкое.

MyApp.country.get(«presidentName»);
// «Barack Obama»
Mingan Согласен, это было моим упущением, исправил. Можете наслаждаться переведенными комментариями!
Спасибо! Так действительно намного лучше. И статья даже читается как-то более на одном дыхании что ли :)
Ни одного примера про reconfigured.
А годные полифилы имеются? Гитхаб-сечинг выдал только этот, который не выглядит особенно рабочим.
Тут можно сделать только через свой особый объект. И ставить все свойства через метод set, remove. Всё остальное будет по скорости проигрывать как на диаграмме выше.
Можно еще использовать getter и setter, тогда будет выглядить как объект (я пробовал — работает =). Но тут опять же мы фиксируем «схему» объекта.
А через сет\гет получается как раз обходной полифил, который будет работать в IE 5. Ext.js пошли по этому пути очень давно.
Ага, сам таким пользуюсь, когда ie8 нужен.
Пока не нашел ничего кроме полимеровского(который описан в статье)
Без вменяемых полифилов для ИЕ всё это пока дела будущего.
Я не могу себе представить полифил для такого функционала. Невозможно отследить изменения свойства объекта не через акцессор. Думаю, как только спецификация будет окончательно утверждена, в ближайших на тот момент версиях появится поддержка такого функционала, даже в IE(разумеется, речь идет только об edge-версиях)
Автора переполняют эмоции, хотя если разобраться, то окажется, что `Object.defineProperty` уже давно удовлетваряет всем желаниям. Единственное не возможно следить за добавлением/удалением свойств, но это крайне редкая необходимость по двум простым причинам:
1* Архитектурная — модели и классы должны быть полноценны и однозначны
2* Производительная
— добавляя-удаляя свойства обьекта, V8 как минимум, пересоздает скрытые классы для обьекта
— создается небольшой event flood, так как нужно фильтровать `changes`, что бы слушать только например `foo property update`
В наших проэктах давно уже завели себе Object.[add/remove]Observer Object.[lock/unlock]Observers которые добавляют ака proxy функции для сеттеров и ака breadcrumbs proxies для вложенных обьектов, как с примера для полимера.
var obj = { foo: { bar: 'baz' } };
Object.addObserver(obj, 'foo.bar', console.log.bind(console));
obj.foo.baz = 'qux';
//> qux
obj.foo = { bar: 'quxx' }
//> quxx


И ещё, `getNotifier` отлично заменяется `EventEmitter`ом. А что бы следить за массивом, достаточно обернуть его мутаторы, сново же, своим proxy методом.

Я никаким образом не хочу сказать, что O.o плох — напротив, и статья отличная, только много из этих вещей можно и нужно использовать уже сейчас! Ну, кто может себе позволить IE9+;
Я тоже делал похожую вещь, для своего проектика (тут если интересно).
Пример из readme
var model = require('moco').model;

var User = model()
  .attr('_id', { primary: true }) // this attribute will be used as primary key
  .attr('name') // just simple attribute
  .attr('email', { get: function() {
    return this.name + '@example.com';
  }}) // this is a getter and it called each time you try access this model
  .attr('title', { default: 'Unknow' })// this will be used to fill undefined attribute while creation

var u1 = new User({ _id: 1, name: 'den'});
console.log(u1._id); // 1
console.log(u1.primary); // 1

console.log(u1.email); // den@example.com
console.log(u1.title); // Unknow

u1.name = 'daniel';

console.log(u1.email); // daniel@example.com
Только функциональность, а не функционал. Специально не пишу в личку, ибо в последнее время болезнь приобрела массовый характер (впрочем, ощущение, что уже пора смириться).
Революция! Грядёт революция! Она изменит всё! Ветер перемен! Она изменит всё, что вы знали о дата-байндинге! Она полностью изменит подход! Саму концепцию! Вы никогда раньше такого не видели!!! Вы больше не увидите старого джаваскрипта!!! Вы готовы?! Вас ждёт погружение в новый мир! Мир, в котором на каждой строчке используется слово дата-байндинг! Вы готовы?! Я спрашиваю, ВЫ ГОТОВЫЫЫ!!!???
Как «автор фреймворков» не вижу особого повода для радости.
1. Многие всё ещё поддерживают ie8 где даже акцессоров толком нет.
2. В сравнении с ангуляровскими грязными проверками любой фреймворк выглядит как манна небесная.
3. Никто находясь в трезвом уме не будет светить полями наружу — только через акцессоры. Соответственно вся подписка/отписка/нотификации будут делаться как и сейчас — вручную. Новое апи тут вносит лишь неоднородность реализации не давая ощутимого профита.
4. Единственное полезное применение — отслеживать изменение в чужих объектах. Особенно полезно это было бы для хостовых объектов. Но о них в статье ни слова и что-то мне подсказывает, что с ними будет всё как обычно — плохо.
5. Никак не решена проблема холостых вычислений. Например, переменная А зависит от C и B, а B зависит от C. В результате когда изменится С сначала будет вычислена А, потом В, а потом снова А. В общем с этим АПИ будет та же беда, что и с нокаутом:
диаграмма: nin-jin.github.io/slide/#slide=induction
тест: jsperf.com/reactive-libraries-comparison
6. Они это апи точно согласовали с остальными игроками? А то получится, что в хроме Object.observe, в мозилле watch, а ie вообще не при делах.
5. A зависит от C и B, B зависит от C. Когда изменится C, без разницы, что будет изменено раньше, A или B, т.к. событие произойдет только после обработки обоих микрозадач. В крайнейм случае, если я ошибаюсь (а это вряд ли, см. статью), всегда можно перегрузить акцессор и создавать свои нотификации только в том случае, если оба свойства (B и C) будут изменены.
Даже со стороны наблюдателя, вы не хотите, чтобы какая-то сторонняя функция была вызвана из середины текущей функции и т.п. Несогласованность и разобщенность мест вызовов функций раздражает, верно? И прибавьте к этому ещё проверки на ошибки, и прочие ситуации, которые могут усложнить жизнь при данном подходе. И в результате мы видим, что с подобной моделью реально трудно работать. Асинхронный подход сложнее в понимании, но всё же, на сегодняшний день, ничего лучше него нет.


Здесь с автором не соглашусь. В большинстве случаев, как раз, мы хотим, чтобы все изменения обрабатывались сразу же. Если вы меняете поле A, то вы хотите, чтобы поле B = A + C изменилось сразу же. Если вы добавляете элемент в массив данных, то вы хотите, чтобы элемент добавился и в массив представлений сразу же. Иначе пришлось бы запускать таймер на 1 мс, чтобы дождаться рендеринга представления, или использовать другой костыль, если вам нужно обратиться к этому представлению. Помню, часто сталкивался с такой проблемой, когда программировал на ExtJS 2.0 — изрядно бесило. И обработка ошибок с синхронным подходом куда проще — в стек-трейсе сразу видно, где косяк.

Единственная причина использовать отложенные нотификации — это ликвидация многократного пересчета одного и того же значения с целью оптимизации. Например, если пользователь кликает по кнопке «выбрать все записи», мы не хотим, чтобы свойство «выбрана ли хотя бы одна запись?» пересчитывалось N раз.

Согласен со всеми комментариями: область применения данного нововведения весьма и весьма ограничена. Не понятно, зачем ради такой мелочи расширять стандарт ECMAScript, ведь фреймворки итак замечательно решают эту задачу, притом без видимого влияния на производительность (dirty check не в счет). И вообще, API не идеален: с таким event flood все будет тормозить еще больше.
Это отличная возомжность реализовать нативный дата-байндинг. О каком event flood вы говорите? Вы с такой скоростью меняете данные? Даже если и так, то каждый раз, когда мы двигаем мышь, так же возникают события. Я не вижу ничего плохого в расширении ES, тем более, что Вы, скорее всего, даже не заметите, как поменяется начинка всех современных фреймворков в сторону О.о
Как я описал выше — будут лишние вызовы обработчиков, от которых придётся избавляться дополнительными костылями, которые будут буферизировать события.

Кстати, куда можно написать, чтобы предложить разработчикам браузеров реализовать более полезное апи?
Я думаю, что тут вы сможете найти всю интересующую вас информацию.

Как я описал выше — будут лишние вызовы обработчиков

Я сильно извиняюсь, но я до сих пор не понимаю, о чём вы говорите. Если данные меняются блочно, например, через сеттер, то оповещение возникнет только в конце очереди микрозадач, т.е. когда все N свойств изменятся. Если изменяется одно свойство — оповещение происходит сразу. Опишите пожалуйста кейс, когда возникнут лишние вызовы?
Я хочу прослушивать только update у поля foo. Для этого мне надо прослушивать все изменения. Независимо от того, что произошло, и в каком поле объекта, обработчик будет срабатывать. Получается такой нелепый код.

var model = {
    foo: 1
};
Object.observe(model, function(changes) {
    changes.forEach(function(change) {
        if (change.type === "update" && change.name === "foo") {
            console.log(change.type, change.name, change.oldValue);
        }
    });
});


Это и называется event flood.
Извините, если разочаровал :)

var model = {
    foo: 1
};
Object.observe(model.foo, function(ev) {
    if (ev.type === 'update') {
        console.log(ev.type, ev.name, ev.oldValue);
    }
});
var obj = { foo: { bar: 'baz' } };

var observer = new PathObserver(obj, 'foo.bar', ['update']);
observer.open(function(newValue, oldValue) {});

Хотя это только через полифил :(
Ну вот, а если полифил опирается на этот стандарт, то где-то там внутри он фильтрует этот самый event flood. То есть вычислительная сложность такого API далеко не оптимальна. Надеюсь, tenshi сумеет убедить консорциум исправить этот косяк ;)
Отличная статья, но не хватает чуточку информации о привязке к DOM… Не сочтите за наглость мою просьбу немного дополнить и пояснить как использовать O.o(), например, для li элементов?
Похоже что Object.observe отжил, авторы хотят вырезать его (переписка, сообщение).
Предположительные причины — медленный (Object.defineProperty работает быстрее*) и сложности использовать в фреймворках (например его пытались внедрить в Angular 1, а в Angular 2, не смотря на обещания, его по прежнему нет).
На данный момент Object.observe используется в Polymer.js* и Angular Light.

Кроме того «на подходе» Proxy из ES6 (который уже есть* в FF и IE, а так же в Chrome но с флагом).
Sign up to leave a comment.

Articles