I have two very simple Spine.js controllers:
class ListController extends Spine.Controller
className: 'list'
constructor: () ->
super
class DetailController extends Spine.Controller
className: 'detail'
constructor: () ->
super
controller stack
class Application extends Spine.Stack
className: 'mystack'
controllers:
list: ListController
detail: DetailController
and corresponding HTML markup
<div class="mystack">
<div class="list">list</div>
<div class="detail">detail</div>
</div>
My problem is that when controller stack instantiated
app = new Application()
app.list.active()
there is no active class added to the div.list element. Divs remain unchanged.
What is wrong with that?
I've just got it so I'll describe basic working example. There are several issues with the code above (caused by my misunderstanding of how Spine.js controller stack works :-)
First, appropriate HTML element have to be associated with every controller managed by the stack. When controller stack instantiates the controller it passes only stack (i.e. itself) instance as parameter to the constructor. So controller constructor have to take it into account (e.g. like the following):
class ListController extends Spine.Controller
constructor: (parameters) ->
#stack = parameters.stack
#el = $ #stack.settings.listSelector
super
class DetailController extends Spine.Controller
constructor: (parameters) ->
#stack = parameters.stack
#el = $ #stack.settings.detailSelector
super
and the stack:
class Application extends Spine.Stack
settings:
listSelector: '.list'
detailSelector: '.detail'
controllers:
list: ListController
detail: DetailController
default:
'list'
then the controller stack could be instantiated:
app = new Application
el: $ '.mystack'
ListController will be active (i.e. corresponding div has active class added) by default and anytime later you can call #stack.detail.active() or #stack.list.active() from controller instance method to activate required controller and 'hide' (i.e. remove active class) the other(s).
EDIT:
We discussed the issue with #aschmid00. In fact, controller constructor doesn't have to set its own property #stack manually. It is done automatically when base constructor called by super. But in case of this question #el have to be set before base constructor called due to the events delegation etc.
Related
I'm using extbase, fluid system on typo3 to build a backend module.
I Have a Controller "MainController" action called 'AddBoxes' and I have another Controller called BoxElementsController, and there is an action method called 'popupBoxAction'.
I want to render the output of the BoxElementsController->popupBoxAction in the MainController-AddBoxesAction();
so that I can assign the output to my view variable.
How can i achieve this in Typo3 6.1.
Thanks
Also you can fetch data or output whatever you like from BoxElementsRepository
class MainController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
protected $boxElementsRepository;
public function injectBoxElementsRepository(BoxElementsRepository $boxElementsRepository) {
$this->boxElementsRepository = $boxElementsRepository;
}
public function AddBoxesAction(){
$popupBoxActionOutput = $this->boxElementsRepository->popupBox();
$addBoxesAction = $this->mainRepository->findAll();
$this->view->assignMultiple(array(
'popupBoxActionOutput' => $popupBoxActionOutput,
'addBoxesAction' => $addBoxesAction,
));
}
}
Try to instantiate you controller in you action then call ControllerObject->initializeAction() before calling your desired action.
I currently trying out ChaplinJS for a new project and I'm running into a problem.
I want to have a controller (for my navigation) that's listening to the changes of the router. I want to have callbacks for events like changeURL or route. I'm not sure how Chaplin's mediator works but I thought the router is throwing events using the mediator which I should be able to catch. I tried this:
mediator = require 'mediator'
Controller = require 'controllers/base/controller'
Menu = require 'models/menu'
MenuView = require 'views/menu-view'
module.exports = class MenuController extends Controller
listen:
'router:changeURL mediator': #test
initialize: ->
super
#menu = new Menu()
#view = new MenuView model: #menu
mediator.subscribe 'router:changeURL', #test
test: ->
console.log 'testlisten'
You should use beforeAction method to accomplish this.
The method receives all arguments actions receive. http://docs.chaplinjs.org/chaplin.controller.html
There is no listen in controllers.
I have stuck with implementing a simple scenario.
I have 2 views for a single controller
MyController
view/scripts/my/index.phtml
/index2.phtml
I know $this->view->test = "test" will set 'test' view variable for index.phtml.
but I would like to know how to set a variable for index2.phtml.
Setting $this->view->test = "test" in your controller will set view variables that can be used by any templates rendered afterwards with the call:
$this->render('your action');
So for example:
class MyController extends Zend_Controller_Action
{
public function indexAction()
{
$this->view->test = "test"
// Renders my/index.phtml
$this->render();
// Renders my/index2.phtml
$this->render('index2');
}
}
In both templates you have access to the test property.
I'm having real problems writing a simple Backbone.js app using CoffeeScript and Zepto.js
This is the simplest Backbone view yet the events don't fire. I get no errors in the console either? Where am I going wrong?
#Main view
class AppView extends Backbone.View
constructor: ->
#el = $("#books")
#template = _.template("<div>New Item <a href='' id='addNew'> add new item</a></div>")
events: {
"click" : "createNew"
}
render: =>
#el.html(#template())
createNew : ->
console.log "new"
#Onload
$(document).ready ->
view = new AppView
view.render()
I've been following the only example I can find of CoffeeScript & Backbone together https://github.com/bnolan/Backbone-Mobile/blob/master/application.coffee
However if I add super into my view code above I get an undefined error, his code does not.
The class Backbone.View has its own constructor that does plenty of work, and you are overriding it and not calling super. Bad.
Instead, Backbone.View provides you the ability to define your own constructor-type function called initialize. Perform all your setup there. Backbone.View#constructor will call initialize.
#Main view
class AppView extends Backbone.View
initialize: ->
#el = $("#books")
#template = _.template(
"<div>New Item <a href='' id='addNew'> add new item</a></div>"
)
I had a similar problem (events not firing) and found that the problem was due to not setting #el. I set that:
#el: $("#content")
and it worked.
i have a custom helper written which returns the html form as string which extends the Zend_view-hepler_Abstract
Now i have 3 helpers .How do i assign each helper to a different view .
It is something like this in the controller
class abc extends Zend_controller_front{
public action page1Action (){
// I want to use a different Helper
//How do i assign custom1 helper to this view Separately
}
public action page2Action (){
// I want to use a different Helper
//How do i assign custom2 helper to this view Separately
}
public action page3Action (){
// I want to use a different Helper
//How do i assign custom3 helper to this view Separately
}
}
um, should you be inheriting from Zend_Controller_Action not Zend_Controller_Front?
also the word 'action' is not a valid php keyword?
just use the view helper in your view script, so in abc/page1.phtml
print $this->page1Helper()
similarly for page2 and page3
but there may be an easier way... you can just
print $this->form;
and the form will print without the need for a helper?