mikeric / rivets

Lightweight and powerful data binding.

Home Page:http://rivetsjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

https://github.com/blikblum/tinybind