DOM not updating when model changes on onclick
mm-ns opened this issue · comments
I am using rivets to bind news stories i retrieve from http call to my dom; It's paginated so i load 3 at a time.
<section class="news-section">
<div class="col-12 post" rv-each-new="news">
<h5 class="h4capslight mb-3">{new.date}
<a href="" class="h4capslink">NEWS</a>
</h5>
<a href="#newsroom-post">
<h1 class="mb-3">{new.title}</h1>
</a>
<a href="#newsroom-post">
<p class="post-desc mb-4">{new.content}</p>
</a>
<a class="link-underline" href="#newsroom-post">Read More</a>
</div>
<div class="col-12 mt-5">
<nav aria-label="navigation">
<ul class="pagination">
<li class="page-item" rv-each-page="numberOfPages" rv-on-click="loadPage">
<a class="page-link" href="javascript:void(0)" value="index">{ index | mathadd 1 }</a>
</li>
</ul>
</nav>
</div>
</section>
in my js i do this:
$.ajax({
url: "api/items?",
type: 'get',
headers: {
....
},
data: {
....
},
success: function (r) {
news = r.xyz;
newsBinds = rivets.bind($('.news-section'), {
news: news,
page: page,
loadPage: function(e,model){
//here I tried to do another call to fetch more data or do a recursive call to this function.
then when i get the new data i do --> newsBinds.news = news;
}
})
},error:function(xhr){
}
the model is updated correctly in all various attempts i made but the html never gets updated. any ideas what im doing wrong?
So this is bizzare.
As I retrieved from the server additional news, I was doing the following:
model.news = news;
newsBinds.unbind();
newsBinds.bind();
where model is the model i get in the onclick function code. I consoled-out the new model and it is updated correctly although the HTML did not update at all. But if i do this:
model.news[0] = news[0];
model.news[1] = news[1];
model.news[2] = news[2];
newsBinds.unbind();
newsBinds.bind();
Then it works. What am I missing?
I found that if i use the original view (my var newsBinds) i can do newsBinds.models.news = news and that works. it's just not super clear why it wouldn't work in the first case above.
I haven't used Rivets in a long time, but from memory, Rivets uses getters/setters on each child of the model object to track updates to it. By doing model.news = news
, you're replacing the whole news
child object, thereby deleting the getters/setters and bypassing Rivets’ data binding system. However, by doing model.news[0] = news[0]
you're updating the news
child, which Rivets can observe and therefore it can then update the html accordingly. A simpler approach would be Object.assign(model.news, news)
.
Also, I'm not sure about the unbind/bind
lines – I don't remember ever having to do that. Do you actually need those lines? Does it work without?
@mm-ns
You can try tinybind, a fork of rivets with many bug fixes, like this one, and other improvements