Git Product home page Git Product logo

Comments (6)

mweststrate avatar mweststrate commented on May 22, 2024

Hi david,

The short answer is: the controller functions themselves are not reactieve,
they are imperative but alter reactieve data. Thats why they are defined
outside the makereactieve call. I owe you a longer answer but i am a bit
occupied atm. I hope this points in the right direction.

Op zaterdag 8 augustus 2015 heeft David Schalk [email protected]
het volgende geschreven:

In the README example, It seemed odd to define the todoStore methods
addTodo, removeTodo, and loadTodosAsync outside of todoStore rather than
inside like completedCount. I tried to put the method definition inside of
todoStore and the app failed every time. I ended up with this ES6 version:

var todoStore = mobservable.makeReactive({
todos: [
{
title: 'Find a clean mug',
completed: true
},
{
title: 'Make coffee',
completed: false
}
],
completedCount: function() {
return this.todos.filter((todo) => todo.completed).length;
},
pending: 0
});
todoStore.addTodo = function(title) {
this.todos.push({
title: title,
completed: false
});
};
todoStore.removeTodo = function(todo) {
this.todos.splice(this.todos.indexOf(todo), 1);
};
todoStore.loadTodosAsync = function() {
this.pending++;
setTimeout(function() {
this.addTodo('Asynchronously created todo');
this.pending--;
}.bind(this), 2000);
};
var TodoList = mobservable.reactiveComponent(React.createClass({
render: function() {
var store = this.props.store;
return (



    { store.todos.map((todo, idx) =>
    (<TodoView store={ store } todo={ todo } key={ idx } />)
    ) }
    { store.pending ? (
  • Loading more items...
  • ) : null }



Completed { store.completedCount } of { store.todos.length } items.

<button onClick={ this.onNewTodo }>New Todo
<button onClick={ this.loadMore }>Load more...
);
},

onNewTodo: function() {
    this.props.store.addTodo(prompt('Enter a new todo:', 'Try mobservable at home!'));
},

loadMore: function() {
    this.props.store.loadTodosAsync();
}

}));
var TodoView = mobservable.reactiveComponent(React.createClass({
render: function() {
var todo = this.props.todo;
return (


  • <input type='checkbox' checked={ todo.completed } onChange={ this.onToggleCompleted } />
    {todo.title}{' '}
    <a href='#' onClick={ this.onEdit }>[edit]
    <a href='#' onClick={ this.onRemove }>[remove]
  • );
    },

    onToggleCompleted: function() {
        this.props.todo.completed = !this.props.todo.completed;
    },
    
    onEdit: function(e) {
        e.preventDefault();
        this.props.todo.title = prompt('Todo:', this.props.todo.title);
    },
    
    onRemove: function(e) {
        e.preventDefault();
        this.props.store.removeTodo(this.props.todo);
    }
    

    }));

    React.render(, document.getElementById('approot'));

    It is fully functional, but I still can't define the methods inside of the
    todoStore object.

    I admit that I haven't studied the code. Before I do, I wonder if you
    might give me a hint or two regarding what is going on with defining
    methods outside of objects. I am very impressed with the fresh thinking
    behind this library, and with the elegant simplicity of Mobservable,
    especially in comparison with Flux and its progeny. I am eager to use it,
    but first I want to prepare a little for whatever surprises might lie ahead.


    Reply to this email directly or view it on GitHub
    #13.

    from mobx.

    mweststrate avatar mweststrate commented on May 22, 2024

    @dschalk

    You can easily define reactive properties and normal properties / method on the same object if you use constructor function or ES6 classes. In that case todostore would like as follows:

    With constructor function:

    function todoStore() {
        mobservable.extendReactive(this, { 
           todos: [
            /* .. */
        ],
        completedCount: function() {
            return this.todos.filter((todo) => todo.completed).length;
        },
        pending: 0
    });
    
    todoStore.prototype.addTodo = function(todo) {
       /* ... */
    }

    With ES6 or Typescript classes, you can also use the mobservable.observable decorator (annotation):

    class TodoStore {
    
       @observable todos = [];
    
       @observable get completedCount() {
            return this.todos.filter((todo) => todo.completed).length;
        }
    
       addTodo(todo) {
          /* .. */
       }
    }

    With both this approaches, todo and completedCount properties will be reactive. In general you have three kind of things in your classes

    1. core data, such as todos if you make those reactive you can
    2. define derived data, like completedCount, which reactively updates when the core data changes
    3. methods that alter the core data. Those are not reactive; (otherwise your core data should become reactive data based on the invocation of your actions, which themselves might then become reactive upon the events fired in the browser. Things like RxJs and Baconjs often take this full stack reactiveness. You could do the same with mobservable, but I think that often makes code less understandable)

    from mobx.

    dschalk avatar dschalk commented on May 22, 2024

    Thank you Michel. What I vaguely understood yesterday is crystal clear today. I was reluctant to abandon immutable data and the PureRenderMixin, but I no longer have any reservations. I can't think of any reason not to do things the simple, elegant way you have demonstrated.

    from mobx.

    mweststrate avatar mweststrate commented on May 22, 2024

    Hi @dschalk. The updated docs are progressing steadily, they should make these things more clear. In the mean time, could I quote your last comment on the new homepage guide I'm writing?

    from mobx.

    mweststrate avatar mweststrate commented on May 22, 2024

    I've updated the docs with details about how (and why) to combine reactive and non-reactive properties to objects. I'll hope that makes stuff clearer for new people.

    from mobx.

    dschalk avatar dschalk commented on May 22, 2024

    Here's a link that demonstrates the distinction between defining methods internally or externally: http://schalk.ninja . Every invocation of "render()" causes an internally defined method to execute, even though nothing related to the method changes. It executes every time I roll over the rollover buttons.The code is at https://github.com/dschalk/mobservable-react-buttons.

    The main point of this little project is to show that mobservable can facilitate the creation of highly functional, good-looking rollover buttons. The group buttons resemble ordinary select/option form buttons, but when a user writes in a name not included in the buttons, they all become unselected. And when a user enters a name which is included among the buttons, the corresponding button lights up. Making an HTML form do all of this would be an ugly hack. With mobservable, it is easy and natural. Buttons light up whenever 'group' has a corresponding value. It's all automated by one simple method in a mobservable-encapsulated object.

    from mobx.

    Related Issues (20)

    Recommend Projects

    • React photo React

      A declarative, efficient, and flexible JavaScript library for building user interfaces.

    • Vue.js photo Vue.js

      🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

    • Typescript photo Typescript

      TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    • TensorFlow photo TensorFlow

      An Open Source Machine Learning Framework for Everyone

    • Django photo Django

      The Web framework for perfectionists with deadlines.

    • D3 photo D3

      Bring data to life with SVG, Canvas and HTML. 📊📈🎉

    Recommend Topics

    • javascript

      JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

    • web

      Some thing interesting about web. New door for the world.

    • server

      A server is a program made to process requests and deliver data to clients.

    • Machine learning

      Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

    • Game

      Some thing interesting about game, make everyone happy.

    Recommend Org

    • Facebook photo Facebook

      We are working to build community through open source technology. NB: members must have two-factor auth.

    • Microsoft photo Microsoft

      Open source projects and samples from Microsoft.

    • Google photo Google

      Google ❤️ Open Source for everyone.

    • D3 photo D3

      Data-Driven Documents codes.