Giter Site home page Giter Site logo

ember-memento's Introduction

Ember-Memento Build Status

A mixin for Ember.js which adds undo/redo functionality to Ember.Object's.

Added functionality to an object with the Ember.Memento mixin:

Usage

Add the mixin, located in app/lib/memento.js to your project.

The mixin works with properties of type 'string', 'number', 'boolean' and 'array'.

Use it in your objects which shall offer the functionality like this, see JSFiddle:

var obj = Ember.Object.create(Ember.Memento, {
    // array of properties which shall be considered in undo/redo
    mementoProperties: 'firstName lastName age tags'.w(),

    firstName: 'Buster',
    age: 35,
    tags: ['cartographer']
});

// firstName = 'Buster', lastName = undefined, age = 35, tags = ['brother', 'cartographer']
obj.getProperties('firstName lastName age tags'.w());

Properties are modified as usual via Ember.js setter's

obj.set('lastName', 'Bluth');
obj.get('tags').pushObject('step-brother');
obj.set('firstName', 'Baby Buster');

// firstName = 'Baby Buster', lastName = 'Bluth', age = 35, tags = ['cartographer', 'step-brother']
obj.getProperties('firstName lastName age tags'.w());

undo

To undo a change, simply call undo on the object:

// undo last change of firstName
obj.undo();

// firstName = 'Buster', lastName = 'Bluth', age = 35, tags = ['cartographer', 'step-brother']
obj.getProperties('firstName lastName age tags'.w());

// undo last change of adding 'step-brother' to tags array
obj.undo();

// firstName = 'Buster', lastName = 'Bluth', age = 35, tags = ['cartographer']
obj.getProperties('firstName lastName age tags'.w());

// check if an undo is possible
if (obj.get('canUndo')) {
    ...
}

// get the number of steps which can be undone
var numOfPossibleUndos = obj.get('undoCount');

redo

To redo a change, simply call redo on the object:

// redo change and re-add 'step-brother'
obj.redo();

// firstName = 'Buster', lastName = 'Bluth', age = 35, tags = ['cartographer', 'step-brother']
obj.getProperties('firstName lastName age tags'.w());

// redo the change to firstName
obj.redo();

// firstName = 'Baby Buster', lastName = 'Bluth', age = 35, tags = ['cartographer', 'step-brother']
obj.getProperties('firstName lastName age tags'.w());

// check if a redo is possible
if (obj.get('canRedo')) {
    ...
}

// get the number of steps which can be redone
var numOfPossibleRedos = obj.get('redoCount');

mementoSize

By specifying a property mementoSize you define how many history states should be remembered. By default, the whole history is saved:

// only save the latest 2 history states
obj.set('mementoSize', 2);

obj.set('firstName', 'Tobias');
obj.set('firstName', 'Tobias Fünke');
obj.set('firstName', 'Dr. Tobias Fünke');
obj.set('firstName', 'Nelly');

obj.undo(); // firstName = 'Dr. Tobias Fünke'
obj.undo(); // firstName = 'Tobias Fünke'
obj.get('canUndo'); // false

clearHistory

The history can be cleared via clearHistory method. If no parameter is specified, the whole history is cleared. You can also pass the number of history items which shall be kept:

obj.set('firstName', 'Tobias');
obj.set('firstName', 'Tobias Fünke');

// compact history and only keep 1 item
obj.clearHistory(1);

obj.undo(); // changes firstName to 'Tobias'
obj.undo(); // does nothing since there are no more history items

updateProperties

To change multiple properties and only add 1 history item, use the updateProperties method:

obj.set('firstName', 'Buster');
obj.set('age', 100);

// update multiple properties at once, but create only 1 histroy item
obj.updateProperties({
    firstName: 'Baby Buster',
    age: 42
});

// firstName = 'Baby Buster', age = 42
obj.getProperties('firstName age'.w());

// undo last change
obj.undo();

// firstName = 'Buster', age = 100
obj.getProperties('firstName age'.w());

Development

The mixin is located at app/lib/memento.js and the corresponding tests are at app/tests/.

Test

You can test the mixin via:

$ bundle install 
$ bundle exec rake test

Or if you're on a Mac, via:

$ bundle exec rake autotest

This executes the tests by using Phantom.JS, which you need to have installed.

Or you can run the tests via:

$ bundle exec rackup
$ open http://localhost:9292/tests/index.html

Thanks

This project's layout is based on the fabulous interline/ember-skelton

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.