2015-05-20 3 views
2

Скажем у вас есть объект с методом:В Угловом, каким образом вы можете автоматически обновлять привязку данных, привязанную к методу?

/* 
chat.author == a String 
chat.message == a String 
chat.timestamp == a Date 
chat.timeago() == a method that returns a string, like "2 minutes ago" 
*/ 

И ваш HTML выглядит примерно так:

<div>{{ chat.author }}</div> 
<div>{{ chat.message }}</div> 
<div>{{ chat.timeago() }}</div> 

возвращаемое значение chat.timeago() будет меняться в зависимости от времени, прошедшего с момента чата .timestamp, поэтому он может измениться с «только сейчас», «несколько секунд назад», до «минуты назад», «2 часа назад» и т. д.

Какие существуют опции, чтобы указать Угловое, когда необходимо обновить данные, привязанные к методу, и какая опция является наиболее el egant или традиционным способом в Angular?

+1

Я бы предложил использовать директиву для представления timeago и просто использовать определенные интервалы и нарисовать ее вручную на ui с помощью собственной операции DOM, такой как 'innerHTML' или даже с jqlite .text/.html. Если вы используете $ timeout, $ interval (очень плохо), он снова запустит цикл дайджеста и всех наблюдателей ... Просто чтобы обновить timeago, это слишком много, особенно когда ваше приложение становится больше. С угловым вы должны ответить на цикл дайджеста, чтобы обновить привязки, и вы закончите делать тайм-аут и т. Д., Который имеет свои недостатки. – PSL

+0

@PSL Хорошая точка здесь. Директива была бы более сложным, но лучшим способом добиться этого. – Okazari

+0

@Okazari да, но это будет определенно стоить, но не сложнее реализовать. Пила во время последнего ng-conf была презентация, где это обсуждалось, даже для эффектов mouseover/mouseout не используют ng- * события, а просто связывают события вручную. На более крупном ui или (когда он станет больше) вы получите серьезные проблемы с производительностью. Так что просто вызовите цикл дайджеста только тогда, когда это действительно стоит. – PSL

ответ

2

Вы должны привязать к области переменной формы и обновить эту переменную, используя $timeout function.

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

1

То, как вы сделали это вполне приемлемо.

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

В стороне, нет никакого преимущества, чтобы выразить выражение внутри $watch, так как есть неявные часы, образованные вашей привязкой.

Редактировать: Если вы хотите, чтобы значение обновлялось с течением времени, используйте службу $timeout/$interval, как и другие.

+1

Я работал в проекте с большой проблемой производительности с угловым. Мы обнаружили, что привязка метода получила более высокую стоимость, чем привязка var. В каждом дайджесте он будет выполнять всю функцию вместо того, чтобы просто сравнивать предыдущее значение с новым значением. Было бы лучше связать переменную и обновить ее в зависимости от нашей потребности. – Okazari

+1

@Okazari Я понимаю вашу заботу - та же проблема возникает, когда вы используете фильтры. Хотя я немного удивлен, что ваши результаты продемонстрировали бы большую часть разницы. Мне бы хотелось увидеть jsperf. –

+2

Команда нарушила почти все веб-стандарты (спросил клиент) и сделал некоторые уродливые вещи. Мы много работали, чтобы найти, откуда все эти проблемы. Это было очень много, включая этот. Только мелочи, но LOT (между 2000 и 6000 привязкой на странице). Зал стыда был привязан к функциям и использованию $ watch. – Okazari

1

На мой взгляд, это должно выглядеть следующим образом:

<div>{{ chat.author }}</div> 
<div>{{ chat.message }}</div> 
<div>{{ chat.timeago.time }}{{chat.timeageo.message}}</div> 

в контроллере:

$scope.chat = { 
    author: "Me", 
    message: "Hi!", 
    timeago: { 
     time: 0, 
     message: "seconds ago" 
    } 
} 

Теперь в вашем контроллере вы, вероятно, использовать $interval службу, чтобы обновить «timeago "сообщение

var updateTimeago = function(){ 
    $scope.timeageo += 10; 
}; 
$interval.(updateTimeago(), 10000); 

Каждые десять секунд ваше сообщение будет обновляться.

Изменить это, чтобы сделать все, что вам нужно. Надеюсь, это помогло.

EDIT: Как было предложено PSL, было бы здорово использовать настраиваемую директиву для обновления таймера вместо использования интервала $, который может быть жадным с точки зрения производительности.

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