Jii allows you to encode models - and their relations - variables (strings, integers, arrays, floats, booleans) and urls into their Javascript equivalents. You can also use Jii to store your Javascript functions without polluting the global scope. Since version 0.0.3beta, Jii allows you to perform some basic operation on Javascript models and introduces some functions to interact with Knockout js observables. The aim of this extensions is to keep your server side code as well as your client side one more maintainable. Moreover it aims to ease the process of sharing data beetween PHP and Javascript.
Yii 1.1 or above PHP 5 or above
Copy Jii folder to your applications protected/components folder. And add the following lines to your config/main.php.
'components' => array( ... 'jii' => array( 'class' => 'application.components.Jii.Jii', // uncomment the following // if you do not want to use the minified version // 'script' => 'jii-0.0.4.js', ), ... ),
Adding Jii to your page is easy and can be done as follows:
Yii::app()->clientScript->registerScript('jii', Yii::app()->jii->getScript(), CClientScript::POS_END);
You can add params, urls, models and functions to Jii as follows:
// adding params // you can use any kind of php variable Yii::app()->jii->addParam('your_param', 10); // adding urls Yii::app()->jii->addUrl('view_test_url', $this->createUrl('test/view')); // adding functions Yii::app()->jii->addFunction('function', 'function(){ alert("This is an alert!"); }');
As regards CActiveRecord instances (or class instances inheriting from CModel), you can select which attribute you want Javascript have access to by adding the following method to each of the CActiveRecord class files you wish to convert ...
... public function getJsonizeables() { return array( 'attribute_label_1', 'attribute_label_3', 'attribute_label_4', ); } ...
... and then you can use the following code to add it to Jii:
$jsonized_model = Yii::app()->jii->jsonize($model); // adding models to jii Yii::app()->jii->addModel('model', $jsonized_model);
Since version 0.0.3beta, Yii::app()->jii->addModel() accepts models and dataproviders as well as jsonized data:
$model = new Model(); Yii::app()->jii->addModel('javascript_model', $model);
Since jii 0.0.2 you can jsonize CActiveDataProviders as you do with model instances or model arrays:
$jsonized_data_provider = Yii::app()->jii->jsonize($data_provider); // adding data provider to jii Yii::app()->jii->addModel('model', $jsonized_data_provider);
You can add any function that needs to be executed after the page has finished loading with the following code:
Yii::app()->jii->addBindings('function(){ // the following alert will be shown after // page has finished loading alert("Hello world!"); }');
Sometimes you may need to perform additional operation on models' attributes values before passing them to Javascript. In such cases, you can jsonize custom attributes in the following way. Create or add to the model/model's you wish to jsonize the getJsonizeables method and add to the array a custom attribute name such as custom_attribute_1. After that, create a public method named getcustom_attribute_1() which performs some operation over one ore more model attributes and return a value.
... public function getJsonizeables() { return array( 'attribute_label_1', 'attribute_label_3', 'attribute_label_4', ... 'custom_attribute_1', ); } // the following method allows you to jsonize custom attributes public function getCustom_attribute_1() { return $this->_performSomeOperation($this->attribute_label_1); } ...
Since version 0.0.3beta each Jii model is an object providing the following methods:
/** * Finds one model instance based on the specified attribute * @param object {attribute: "attribute_name", value: attribute_value} * @return object or null if none object is found */ jii.models.javascript_model.findByAttribute(); // the Javascript object representation of a jii Model jii.models.javascript_model.toJS(); // the number of model instances found jii.models.javascript_model.count();
Since Jii 0.0.3beta you will have at your disposition a couple of functions:
/** * Converts a jii model into an Knockout observable * @param object model * @return observable */ jii.utils.observable(); // the same as above except that it returns an observable array jii.utils.observableArray();
2012-12-14 jii 0.0.4
2012-12-13 jii 0.0.3beta
2012-12-12 jii 0.0.3beta
2012-12-10 jii 0.0.2
Total 10 comments
I have just moved a few comments about further or future implementations or request for support of particular features to Jii forum page, in order to make it easier for us to discuss about any topic. Nonetheless I would like to thank you for your feedback, which I always appreciate: thank you. :)
+1 for the forum page (github, roadmap suggestion etc...)
You could also include support for ko mapping plugin, its very good for complex models (ie. nested models).
I haven't tested your code yet, as I already use my own encoding with mapping plugin. Basicly I convert model into array and then encode into json and then pass it to ko.mapping. It supports deeply nested models, arrays of models, just any complex object.
@Cherif Thank you. That is clear. Even if I do not think that behaviors are a suitable approach to this extension (there are a few reasons that it would take to long to explain outside a forum), I think that what you are looking for - and that perhaps will be useful to others and to me too - can be achieved in the following way (of course it actually requires a little more typing:
On your Javascript code:
Anyway I think Jii could become in a near future a Javascript library for Yii. I suggest we use Jii forum page for further comments on this issue: in this way we hopefully will benefit from other people's opinions and suggestions. Many thanks :D
@AustinGeek Well, If you need to encode models to JSON you can use Jii Jsonizer:
If your aim is to decode JSON data into models you can create your own CModel classes defining your custom attributes and validation rules, than you can:
Nice!
I have an external site I need to extract data from and will probably push data to in the future. They have a great API that is REST-FUL and return JSON formatted data. I just don't know how to deal with all the data I get back from the api calls.
The behavior extends CActiveRecordBehavior or CModelBehavior is to place where I suggest to put the code for this extension I want to generate Models for Knockout and convert the Model.attributes to observables and relations (HAS_MANY, MANY_MANY) to obervableArray consider this extension to have an idea ejsonbehavior.
Hope it helps
Thank you for your comment Cherif. I never went deep into behaviours, that is why I'd like you could explain with a few more words which way they could make this extensions easier to use and to maintain. Furthermore I see behaviors as something that can deviate the application flow under particular conditions. But I am not able to identify which conditions you could be thinking about.
Thank you for this, but I suggest to think about it as a behavior will be much easier to use and maintain.
Thank you for your comment. :D I am mainly using knockout js as a Javascript library and this extension have been developed to ease Yii to knockout interactions. I guess this aswers your question. Anyway, I still haven't planned future developements yet, so I am open to and I will appreciate any contribution.
Hi Excellent extension, I can stop wondering if this extension is linked to a much broader prject as using it with frameworks like Backbone ? or other . If it is I'd really be interested in particiapting :) Cheers
Leave a comment
Please login to leave your comment.