Does $changedAttributes in afterSave() is the same as $this->getDirtyAttributes()? - yii2

public function afterSave($insert, $changedAttributes)
{
parent::afterSave($insert, $changedAttributes);
// code for after save
}
From the code above, I'm understanding that the variable $changedAttributes in the afterSave() method are the same with $this->getDirtyAttributes(), right?

No. getDirtyAttributes() returns state after object was saved, while $changedAttributes returns state before save. $changedAttributes also contains only attributes which were saved during save() or update() call, not all changed attributes. So if you have model with two fields: id and name, and:
If you change both fields and call save(), then in afterSave() $this->getDirtyAttributes() will return empty array (since there is no unsaved changes in object) while $changedAttributes will contain both attributes with old values (since both attributes were saved).
If you change both fields and call save(true, ['id']), then $this->getDirtyAttributes() will return array with value of name (since this is changed attribute, but not yet saved) and $changedAttributes will contain array with value of id (since this attribute was updated).
For more insights you can refer to BaseActiveRecord::updateInternal() implementation.

Related

How to clear and reset Mapping of Array in solidity

Below is how I do the record into the mapping array. How can I create a clear|removeall function that clears or reset all the records back to default which is empty?
address payable[] public players;
mapping(address => uint256[]) playerTicket;
function playersRecord() public view returns(uint256[] memory){
return playerTicket[msg.sender];
}
I managed with the below function to clear one by one but not sure how to clear all
function remove(address _addr) public {
// Reset the value to the default value.
delete playerTicket[_addr];
}
You cannot clear all mapping values without specificy the key.
Thus, Solidity doesn't know the keys of the mapping. Since the keys are arbitrary and not stored along, the only way to delete values is to know the key for each stored value.
Your remove() function is correct to clear the values of a specific mapping key.
More information here.

AngularJS: using a function call in ng-readonly with an argument dynamic update

For some of the fields in my webpage they can alternate between being readonly or not readonly. Currently they all have an ng-readonly attribute with a function call like this:
ng-readonly="isReadOnly(field)"
The function isReadOnly does some logic to determine whether it will return true/false.
However I am unsure if this is dynamic, eg. at some points in time isReadOnly can return a different boolean for the same field argument.

Bidirectional binding for flex ComboBox?

I have a collection that I want to bind as data input for a ComboBox:
private static var LOGOS:ArrayCollection = new ArrayCollection([
{index:0, label=logo1},
{index:1, label=logo2}
]);
<s:ComboBox selectedItem="#{model.labelIndex}" labelField="#label" dataProvider="{LOGOS}" />
Now, when selecting an item, the binding should send the associated index property of the objext to the model and update labelIndex.
Of course it does not work as above, because labelIndex is of different datatype than the ArrayCollection.
[Bindable]
private var model:MyModel;
[Bindable]
class MyModel {
public var:Number labelIndex;
}
Question: how can I map the array element to the model and vice versa?
What you are looking for will require some scripting, binding isn't smart enough to figure out how to handle this on its own.
You can use the BindingUtils class to define the bindings, and use the chain argument of the bindProperty method to modify how values are being looked up.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/binding/utils/BindingUtils.html
For the combo.selectedItem to model.labelIndex binding, you can specify the chain as an array, where the elements define the path where to look for the value:
BindingUtils.bindProperty(model, 'labelIndex', combo, ['selectedItem', 'index']);
This will bind to the selectedItem property, and pass the value of the items index property.
The other way around is a little more tricky and will require using a getter function which grabs the object from the datasource, based on the labelIndex value:
BindingUtils.bindProperty(combo, 'selectedItem', model, {
name: 'labelIndex',
getter: function(host:MyModel):Object
{
return LOGOS.source.filter(function(item:Object, index:int, array:Array):Boolean
{
return item.index === host.labelIndex;
})[0];
}
});
This will bind to the labelIndex property, and the getter function will be invoked when the property changes. The function will filter the datasource based on the models changed labelIndex property value, and return the source object with the matching index property value, which will finally be set for the combobox selectedItem property.
Your combobox definition will of course need an id in order to be targetable via script
<s:ComboBox id="combo" dataProvider="{LOGOS}" />
Note that there's no need forthe the # in the labelField property, this is only used with XML datasources where you need to target an attribute. However, actually you don't need to specify this at all, since label is the default value of the labelField property.

How to pass viewData back to the controller from partial view?

I have a main view using several partial Views.
Each of these partials use a different model and have post action.
My problem is I need one property from my main view's model to be used in one of my partials.
The partial view which I need to pass this property view is the last stage in the process.
The application reaches a partial view that contains a switch statement , based on the status on the item being queried, decides which partial will be rendered.
I have the property passing that far and even have it included in the Renderaction for the partial but I don't know how to retrieve it in the controller, PartialViewResult.
In the main view:
#{Html.RenderPartial("StatusForm", Model.HeadingDataModel.Status, new ViewDataDictionary { { "PurchaseOrderNumber", Model.AccordionModel.LtsSpecific.PurchaseOrderNumber } });}
PurchaseOrderNumber is what I'm after. The value gets passed to the next stage:
#{
var obj = ViewData["PurchaseOrderNumber"];
}
And within the same view:
Html.RenderAction("FinishedCalibrationForm", obj);
How can I retreive this in my controller ?? The following is not correct I know, but you get the idea.
public PartialViewResult FinishedCalibrationForm( string obj)
All help is appreciated.
Calling Html.RenderAction or Html.Action is largely the same as Url.Action. There's many different overloads, but essentially, the first parameter is the action name, the second parameter is going to be either the controller name or an anonymous object of route values, and the third parameter will be an anonymous object of route values if the second parameter was used for the controller name.
Anyways, whatever you pass in the route values will be used to find and call the associated action, which includes parameters for the action. So, for your example:
Html.RenderAction("FinishedCalibrationForm", new { obj = obj })
Would properly pass obj into your action method. As you have it now, it's going to interpret the value of obj as the controller name the action is within, which is obviously not correct.

Function.call(someInstance,args) for methodes. Ignores first arg

In as3 there is a flexible way to change object instance, when calling it.
call or apply members of Function object can be called with specific first arg, and reference say us, that this first arg will be "this" pointer inside function. But i've found it wrong.
I'v write little test, listed below.
public class Test
{
private var name:String = "default";
public var test3:Function = test;
public var test2:Function = function()
{
trace(this.name);
}
public function Test(name:String)
{
this.name = name;
}
public function test():void
{
trace(this.name);
}
}
and tested it.
var tmp:Test = new Test("default");
tmp.test(); //out default
tmp.test.call(new Test("new")); //out default
tmp.test2(); //out default
tmp.test2.call(new Test("new2")); //out new2
tmp.test3(); //out default
tmp.test3.call(new Test("new3")); //out default
So, in anonymous function call we can get right output, but not in case of member function.
maybe it's becouse of ambiguous "this" pointer, that should reffer real object instance for correct work, maybe smth else. I dont now, and as3 reference didnt't describe smth about it.
Finally list of questions:
Why so? By me, it's very strange, and looks like undefined behaviour;
How i can achieve that functionality? How to deceive test function like anonymous one? Isn't it call methode target?
It isn't very important, but I'll be glad any good answer. Thanks!
P.S. sorry for my English.
//EDITED: added this statement to all "name" references. Nothing changes.
When invoking the [[Call]] property, the behavior is different for
different types of closures. A closure is an object that contains a
reference to a method, and the [[Call]] property acts differently
depending on whether it is a function, method, or class closure. A
function closure is one that is of a global method that isn't
associated with any instance of a class. A method closure contains an
instance method of a class, and will always remember its original
"this" value.
If the closure is a function closure, then the first argument passed
to [[Call]] is passed on to the method and gets used as the "this"
value. If the first argument is null or undefined, then the global
object will be used as the "this" value for the method.
If the closure is a method closure, then the first argument of
[[Call]] will be ignored, and the saved "this" value for the method
closure will be passed to the method as the first argument. A method
closure records what its original "this" value was and always uses
that instead of the first argument to [[Call]].
If the closure is a class closure, and there is 1 argument passed to
[[Call]] (in addition to the "this" argument), then the call is
treated as a type conversion, and the argument will be coerced to the
type represented by the closure.
http://learn.adobe.com/wiki/display/AVM2/2.4+Method+invocation+notes