New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component update #691

Closed
kojilab opened this Issue Oct 16, 2016 · 9 comments

Comments

Projects
None yet
3 participants
@kojilab
Copy link

kojilab commented Oct 16, 2016

How can I pass a new data/attributes object to a component once it has been initialized using rivets.init ? I've tried .bind, .update on the return of the init method but nothing works.

Thanks

@Namek

This comment has been minimized.

Copy link
Contributor

Namek commented Oct 17, 2016

You should be able to simply update the same object given to bind(). If I don't understand that then please cover your question with some code.

@kojilab

This comment has been minimized.

Copy link

kojilab commented Oct 18, 2016

This is an example

var data = {
  title: 'Some title'
};
var element = document.getElementById('component-container');
var currentComponent = rivets.init('some-component', element, data);

Then later I want to keep the currentComponent and just feed it new data. Not sure how I can do this aside from reinitializing a new one.

Thanks

@Namek

This comment has been minimized.

Copy link
Contributor

Namek commented Oct 18, 2016

data.title = 'Some other Title' should work

@a-koka

This comment has been minimized.

Copy link

a-koka commented Oct 19, 2016

+1

I also tried this and don't see the component getting a new value. I was hoping something similar to a routine but looks like my attributes aren't updating when the data actually updates.

@Namek

This comment has been minimized.

Copy link
Contributor

Namek commented Oct 19, 2016

it works, have a look: http://plnkr.co/edit/rGkAliZvMnJGj74Lf6qU

function $id(q) { return document.querySelector('#'+q) }

document.addEventListener('DOMContentLoaded', () => {
  let data = {
    title: "some title that will change"
  }

  let scope = {
    data: {
      title: "some other title that will change"
    }
  }

  rivets.bind($id('app-1'), data)
  rivets.bind($id('app-2'), scope)

  $id('btn-1').addEventListener('click', () => {
    data.title = "New title"
  })

  $id('btn-2').addEventListener('click', () => {
    scope.data.title = "New title"
  })
})
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rivets/0.9.4/rivets.bundled.min.js"></script>
    <script src="script.js"></script>
  </head>

  <body>
    <div id="app-1">
      {title}
    </div>

    <div id="app-2">
      {data.title}
    </div>

    <button id="btn-1">Change title directly in scope</button>
    <button id="btn-2">Change title in subscope</button>
  </body>

</html>
@a-koka

This comment has been minimized.

Copy link

a-koka commented Oct 19, 2016

This issue is in regards to components. I understand that data usually propagates to binders via a routine and that works very well. The example above does NOT demonstrate a component where the attribute changes value after initialization which is where my problem lies.

Thanks!

@Namek

This comment has been minimized.

Copy link
Contributor

Namek commented Oct 19, 2016

@a-koka yeah sorry, I understood that just after posting. I was in too much in hurry and still wanted to help.

I hope this is what you need:
http://plnkr.co/edit/gXNQuwXDuJHUHvYsppyh

<!DOCTYPE html>
<html>

  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rivets/0.9.4/rivets.bundled.min.js"></script>
  </head>

  <body>
    <div id="app">
      {myCmpData.title}
      <my-component data="myCmpData"></my-component>
    </div>

    <button id="btn-change-title">Change title</button>

    <template id="my-component-template">
      <div style="border:1px solid steelblue">
        The title: {data.title}
      </div>
    </template>

    <script type="text/javascript">
      (() => {
        let $id = id => document.querySelector('#'+id)

        rivets.components['my-component'] = {
          template: () => $id('my-component-template').innerHTML,
          initialize: (el, attrs) => {
            return { data: attrs.data }
          }
        }

        let scope = {
          myCmpData: {
            title: "some title"
          }
        }

        rivets.bind($id('app'), scope)

        $id('btn-change-title').addEventListener('click', () => {
          scope.myCmpData.title = "changed title"
        })
      })()
    </script>
  </body>

</html>
@a-koka

This comment has been minimized.

Copy link

a-koka commented Oct 19, 2016

You're right @Namek! I noticed an issue on my and and I was also using 0.8.1. I have it working now on 0.9.4. Thanks for your quick responses.

@kojilab

This comment has been minimized.

Copy link

kojilab commented Oct 27, 2016

Thanks for those good examples. Helped me a lot.
In my case I have a router library and a component for each page. If the user goes to a page/route that uses the same component, I want to keep that component and just update the model.

So I had to do something like this based on your examples:


    var currentComponentName, currentData;
    app.renderComponent = function(name, data, options) {        

        // if data is null, false or undefined, then create a 404
        if (!data || data === undefined) {
            name = 'not-found';
        }

        if (name != currentComponentName) {
            rivets.init(name, routeEl, data);
            currentComponentName = name;
            currentData = data;
        } else {
            _.each(data, function(v, k) {
                currentData[k] = v;
            });
        }

    };

@kojilab kojilab closed this Oct 27, 2016

@Namek Namek referenced this issue May 24, 2017

Closed

component #709

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment