What Zend View Partial setObjectKey do? - zend-framework

i am reading zend framework docs on zend view partials
If your model is an object, you may
want to have it passed as an object to
the partial script, instead of
serializing it to an array of
variables. You can do this by setting
the 'objectKey' property of the
appropriate helper:
// Tell partial to pass objects as 'model' variable
$view->partial()->setObjectKey('model');
but what does this do. when do i use it and how.

I'm not 100% positive on this, but from what I can tell by looking at the source and documentation is that standard behavior for rendering a partial is that values are passed into it in the form of an associative array. This allows the values to be bound to variables using array keys.
echo $this->partial('partial.phtml', array ('person' => 'joe');
// in my partial..
<h1><?php echo $this->person; ?></h1> //<h1>Joe</h1>
If you pass an object as the third parameter, (ie, partial('partial.phtml', $myobject);), Zend_View_Partial will automatically serialize that object in an associative array, either by a custom implementation of toArray() or it will just grab the public properties via get_object_vars().
However, if you want to pass the whole object, as an object, you need to set the array key that gets transformed into a variable for the partial to reference.
$this->partial()->setObjectKey('myobject');
echo $this->partial('partial.phtml', $myobject);
What benefits this approach has over partial('partial.phtml', array( 'myobject' => $myobject), I'm not sure. Or I could be interpreting the documentation wrong.

Key as in array(key => value)?

Related

Can a JavaScript reference be stored in a Uint32Array?

Can a JavaScript reference be stored in a Uint32Array? I.e., is there some way to coerce or cast a reference to, for example, a function or an object into an element of some kind of TypedArray?

Fluid: Directly access value of array returned by view helper

I've got custom fluid ViewHelper that returns an array, and I'd like to access a value of this array directly in one command.
Currently I'm using two commands:
{vendor:helper() -> v:variable.set(name: 'data')}
Value of foo: {data.foo}
Is there a way to do this in a single command? v:variable.get does not seem suited for this task.
As #Jpsy said, there is the VHS Variable / GetViewHelper.
But the usage should be {v:variable.get(name: '{vendor:helper()}.foo')}.
If you need the returned array of your viewhelper multiple times in your template, it's better to use it the way you already did. Because otherwise you would call the PHP method behind the viewhelper to build and return the array each time you want to access an index of an already previously built array again.
v:variable.get of VHS viewhelpers does exactly what you want:
{v:variable.get(name: 'data.{foo}')}
This returns the item with index {foo} from array data.
You write that you're using a custom ViewHelper.
Can you modify it?
Inside the ViewHelper you can easy assign a Variable with:
$this->templateVariableContainer->add('variable', 'content');
It depends also on what you're really trying to reach. If you want to cicle the array, you should create a different viewhelper
If you want to create the array, and then access all the data in different position, you're looking for the f:alias fluid helper
Int he last situation, where you look a direct access of a property immediately after the helper call and no more about it, you have to change your viewhelper, with an optional value. If the helper recive the value, you return the element, otherwise it returns the entire array

get values of multiple checkboxes in extbase/fluid TYPO3

How to get values of multiple checkboxes checked in frontend template with fluid and use these values in action extbase?
Declare the argument in your controller action and give it a type array or an array-compatible type which can be constructed by the PropertyMapper.
Name all fields the same as this argument.
Post the data and use the argument in the controller action.
This is the correct way of receiving an array as value of a controller argument. Accessing it directly from the request is not recommended, unless you also declared the argument on the controller action. Not doing so will bypass important argument processing.
save them in a form and retrieve the POST data trough:
$this->request->getArgument('variable')

After raising IEnumerable.OrderBy(), the source list was not sorted,why?

1.First I defined an extension method for the IEnumerable.Add() like the code below
public static IEnumerable<T> Add<T, TKey>(this IEnumerable<T> enumerable, T value, Func<T, TKey> orderBy)
{
if (enumerable == null)
return null;
if (enumerable is IList<T>)
{
var list = enumerable as IList<T>;
if (!enumerable.Contains(value))
{
list.Add(value);
enumerable = enumerable.OrderBy(orderBy);
}
}
}
2.Then,I raised the extension method like this to sort the itemlist according to the "Date" property when a new item was added to the list:
itemList.Add(item, o => o.Date);
3.After all,it appears that the "itemList" was not sorted.
4.I followed the extension method and found that "enumerable" was a new instance after "enumerable = enumerable.OrderBy(orderBy)" and it was sorted,but the "list" was not.
5.Then I tried to cast the sorted enumerable to list like "list=enumerable.ToList()",both of them("enumerable" and "list") were sorted.
6.After that ,when the call stack went back to the "itemList.Add(item, o => o.Date);",the "itemList" was not sorted at all!!!
Anyone can give me some advices?Thanks a looooooooooooooooooooooooooooooooot!!
I believe your problem is that the reference to enumerable is being passed by value rather than by reference. See Jon Skeet's article about passing parameters by value or reference for more information about what that means. In short, C# passes a copy of the parameter's reference so assigning a new value to parameter does not change the reference of the object that was passed in. To pass a parameter by reference you specify the ref keyword, but I don't think that will work with an extension method. If you're dead set on making this work I would suggest inserting the items into your List in sorted order, probably requiring that T implement IComparable.
Update:
First off, see the Skeet's article it's really quite informative and I will probably only be half as clear as he is. Second, when you pass an object as a parameter to a method you are passing a copy of the reference. This means you can still access members of the object but, the same way that a value type is passed by copy, if you modify the reference (ie assign it a new value) you wont modify the original reference. Specifying ref means that you are passing a reference to the reference and changing the reference (assigning a value to it) will affect the original object.
Neither OrderBy or ToList will affect the source list. When you did this: list=enumerable.ToList() you changed your variable to point to a whole new list instance.
It appears to me that this method does too much. I would keep adding and sorting as separate operations. The fact that this extends IEnumerable but silently does nothing if the target is not an IList is a code smell.

Rebuilding lazily-built attribute when an underlying attribute changes in Moose

I've got a Moose class with a lazy_build attribute. The value of that attribute is a function of another (non-lazy) attribute.
Suppose somebody instantiates the class with a value of 42 for the required attribute. Then they request the lazy attribute, which is calculated as a function of 42. Then, they have the nerve to change the first attribute!
The lazy one has already been built, so the builder will not get called again, and the lazy attribute is now out-of-date.
I have a solution now where I maintain a "dirty" flag on the required attribute, and an accessor on the lazy one checks the dirty flag and rebuilds it if needed.
However, this seems like a lot of work. Is there a way to handle this within Moose, e.g. using traits?
My typical solution:
has 'attr1' => (
...
trigger => \&clear_attr2,
);
i.e. when attr1 is updated, attr2 is cleared and will be rebuilt when it is next accessed. clear_attr2 comes for free when you use lazy_build. As long as you use the accessor methods, you don't need a 'dirty' flag.
This is a common pattern - some kind of trait to handle 'derived' attributes would be nice.