How to avoid multiple ngIf in Angular's template - templates

I'd like to know what is the best way to avoid using multiple *ngIf in template. For example, in a component's template, depends on the route, i have to generate multiple different elements like that:
<div *ngIf="route == 'page1'">Title for page 1</div>
<div *ngIf="route == 'page2'">Title for page 2</div>
<i *ngIf="route == 'page1'" class="fa fa-message"></i>
<i *ngIf="route == 'page2'" class="fa fa-bell-o"></i>
<div *ngIf="route == 'page1'">
<button>...</button>
</div>
<div *ngIf="route == 'page2'">
<div class="menu"></div>
</div>
It'll become messy soon, so i came up with a solution, in this component's ts file, i defined an array:
arr_1 = [
{ type: "text", content: "Title for page 1" },
{ type: "icon", class: "fa fa-message" },
{ type: "button", content: "..." }
]
arr_2 = [
{ type: "text", content: "Title for page 2" },
{ type: "icon", class: "fa fa-bell-o" },
{ type: "menu", menu_children: [...], class: "menu" }
]
In its template:
<div *ngIf="route == 'page1'">
<generator *ngFor="let ele of arr_1"
[type]="ele.type"
[class]="ele.class"
[content]="ele.content"
[menu_children]="ele.menu_children"
>
</generator>
</div>
<div *ngIf="route == 'page2'">
<generator *ngFor="let ele of arr_2"
[type]="ele.type"
[class]="ele.class"
[content]="ele.content"
[menu_children]="ele.menu_children"
>
</generator>
</div>
And i created a GeneratorComponent that receives the type and generate the corresponding element:
#Component({
selector: 'generator',
...
})
export class GeneratorComponent {
#Input() type: string;
#Input() content: string;
#Input() class: string;
#Input() menu_children: string;
}
GeneratorComponent's template:
<div *ngIf="type == 'text'">{{ content }}</div>
<i *ngIf="type == 'text'">{{ content }}</i>
...
The problem here is the class GeneratorComponent will have multiple properties and they are not used for one reason (for example: content and menu_children have no relation).
Do you have any idea to fix my solution ? Other solutions will be appreciated.
Thanks !

You could use the helper element <ng-container>. It allows to apply structural directives *ngIf, *ngFor, ..., without actually adding an element to the DOM
<ng-container *ngIf="route == 'page1'">
<div>Title for page 1</div>
<i class="fa fa-message"></i>
<div>
<button>...</button>
</div>
</ng-container>
<ng-container *ngIf="route == 'page2'">
<div>Title for page 2</div>
<i class="fa fa-bell-o"></i>
<div>
<div class="menu"></div>
</div>
</ng-container>

<div [ngSwitch]="route">
<generator ngSwitchWhen="page1" *ngFor="let ele of arr_1"
[type]="ele.type"
[class]="ele.class"
[content]="ele.content"
[menu_children]="ele.menu_children">
</generator>
<generator ngSwitchWhen="page2" *ngFor="let ele of arr_2"
[type]="ele.type"
[class]="ele.class"
[content]="ele.content"
[menu_children]="ele.menu_children">
</generator>
</div>

If it depends on route, why not have two components and display the right one based on the current route via router-outlet
i.e. have a Page1Component and Page2Component and configure routes for them in the appropriate routing.ts file
[
..
{
path: 'page1',
component: Page1Component,
},
{
path: 'page2',
component: Page2Component,
},
]
Then each Page component can define exactly what should be displayed.

Related

PayPal API PopUp closes immediately after clicking PayPal button (Sandbox)

I am trying to implement the PayPal API into my Django / Vue checkout system, but everytime i try to access checkout via the paypal checkout buttons, thepopup closes immediately and i get these errors:
Error messages in developer tools
Obviously it has something to do with the cart's items' attributes and i tried to adjust them accordingly, but i can't figure out how to fix it. My Code:
<template>
<div class="page-checkout">
<div class="columns is-multiline">
<div class="column is-12">
<h1 class="title">Kasse</h1>
</div>
<div class="column is-12 box">
<table class="table is-fullwidth">
<thead>
<tr>
<th>Artikel</th>
<th>Preis</th>
<th>Anzahl</th>
<th>Gesamt</th>
</tr>
</thead>
<!-- vue for loop for looping through items in cart and displaying them in a table -->
<tbody>
<tr
v-for="item in cart.items"
v-bind:key="item.product.id"
>
<td>{{ item.product.name }}</td>
<td>{{ item.product.price }}€</td>
<td>{{ item.quantity }}</td>
<td>{{ getItemTotal(item).toFixed(2) }}€</td>
</tr>
</tbody>
<tfoot>
<tr style="font-weight: bolder; font-size: larger;">
<td colspan="2">Insgesamt</td>
<td>{{ cartTotalLength }}</td>
<td>{{ cartTotalPrice.toFixed(2) }}€</td>
</tr>
</tfoot>
</table>
</div>
<!-- Fields for user information -->
<div class="column is-12 box">
<h2 class="subtitle">Versanddetails</h2>
<p class="has-text-grey mb-4">*Felder müssen ausgefüllt sein</p>
<div class="columns is-multline">
<div class="column is-6">
<div class="field">
<label>*Vorname</label>
<div class="control">
<input type="text" class="input" v-model="first_name">
</div>
</div>
<div class="field">
<label>*Nachname</label>
<div class="control">
<input type="text" class="input" v-model="last_name">
</div>
</div>
<div class="field">
<label>*E-Mail</label>
<div class="control">
<input type="email" class="input" v-model="email">
</div>
</div>
<div class="field">
<label>*Telefonnummer</label>
<div class="control">
<input type="text" class="input" v-model="phone">
</div>
</div>
<div class="column is-6">
<div class="field">
<label>*Adresse</label>
<div class="control">
<input type="text" class="input" v-model="address">
</div>
</div>
<div class="field">
<label>*Postleitzahl</label>
<div class="control">
<input type="text" class="input" v-model="zipcode">
</div>
</div>
<div class="field">
<label>*Ort</label>
<div class="control">
<input type="text" class="input" v-model="place">
</div>
</div>
</div>
<!-- looping through errors for authorization -->
<div class="notification is-danger mt-4" v-if="errors.length">
<p v-for="error in errors" v-bind:key="error">{{ error }}</p>
</div>
<hr>
<div id="card-element" class="mb-5"></div>
<!-- Part for PayPal implementation -->
<template v-if="cartTotalLength">
<hr>
<!-- Set up a container element for the button -->
<div id="paypal-button-container"></div>
<!-- Include the PayPal JavaScript SDK -->
<div ref="paypal"></div>
<!-- <button class="button is-dark" #click="submitForm">Weiter mit PayPal</button> -->
</template>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'Checkout',
data() {
return {
loaded: false,
paidFor: false,
cart: {
items: []
},
stripe: {},
card: {},
first_name: '',
last_name: '',
email: '',
phone: '',
address: '',
zipcode: '',
place: '',
errors: []
}
},
mounted() {
document.title = 'Kasse | RELOAD'
this.cart = this.$store.state.cart
// Imported PayPal functionality from https://fireship.io/lessons/paypal-checkout-frontend/
const script = document.createElement("script");
script.src = "https://www.paypal.com/sdk/js?client-id=AeAKmRDX7HTesdUvfqYqCQz3fZHIkjAoQ5-BG6K-7xnL5GBMVvwQba53v-I8Fx1p9wurUtoBuk7D6bV1"; // Replace YOUR-CLIENT-ID with paypal credentials
script.addEventListener("load", this.setLoaded);
document.body.appendChild(script); // Adds script to the document's body
},
watch: {
$route(to, from,) {
if (to.name === 'Category') {
this.getCategory()
}
}
},
methods: {
getItemTotal(item) {
return item.quantity * item.product.price
},
// Authorization methods
submitForm() {
this.errors = []
if (this.first_name === '') {
this.errors.push('Bitte Vornamen angeben')
}
if (this.last_name === '') {
this.errors.push('Bitte Nachnamen angeben')
}
if (this.email === '') {
this.errors.push('Bitte E-Mail angeben')
}
if (this.phone === '') {
this.errors.push('Bitte Telefonnummer angeben')
}
if (this.adress === '') {
this.errors.push('Bitte Adresse angeben')
}
if (this.zipcode === '') {
this.errors.push('Bitte Postleitzahl angeben')
}
if (this.place === '') {
this.errors.push('Bitte Ort angeben')
}
},
// Imported PayPal functionality from https://fireship.io/lessons/paypal-checkout-frontend/
setLoaded() {
this.loaded = true;
window.paypal
.Buttons({
// createOrder: (data, actions) => {
// return actions.order.create({
// purchase_units: [
// {
// description: this.product.description,
// amount: {
// currency_code: "EUR",
// value: this.product.price
// }
// }
// ]
createOrder: (data, actions) => {
return actions.order.create({
"purchase_units": [{
"amount": {
"currency_code": "EUR",
"value": item.product.price,
"breakdown": {
"item_total": { /* Required when including the items array */
"currency_code": "EUR",
"value": item.quantity * product.price
}
}
},
"items": [
{
"name": item.product.name, /* Shows within upper-right dropdown during payment approval */
"description": item.product.description, /* Item details will also be in the completed paypal.com transaction view */
"unit_amount": {
"currency_code": "EUR",
"value": item.product.price
},
"quantity": item.product.quantity
},
]
}]
});
},
onApprove: async (data, actions) => {
const order = await actions.order.capture();
this.paidFor = true;
console.log(order);
},
onError: err => {
console.log(err);
}
})
.render(this.$refs.paypal);
}
},
computed: {
// Computing total price and total amount of all items
cartTotalPrice() {
return this.cart.items.reduce((acc, curVal) => {
return acc += curVal.product.price * curVal.quantity
}, 0)
},
cartTotalLength() {
return this.cart.items.reduce((acc, curVal) => {
return acc += curVal.quantity
}, 0)
}
}
}
</script>
The createOrder function inside setLoaded() is assigning properties using item although it's not clear where item comes from as it's not being passed in from anywhere:
setLoaded() {
this.loaded = true;
window.paypal.Buttons({
createOrder: (data, actions) => {
return actions.order.create({
purchase_units: [
{
amount: {
currency_code: "EUR",
value: item.product.price, // <--- item is not defined here
breakdown: {
item_total: {
currency_code: "EUR",
value: item.quantity * product.price, // <--- or here
},
},
},
...
If you mean to reference the items in the cart data property you need to use this.cart.items and possibly loop through it if you're trying to send individual item details.

braintree hosted payment fields client undefined Ember 3.25

Ember and Braintree Hosted Fields are not a good mix so far, Braintree Support are out of ideas on this one. When the form renders on the page it calls the action to create the client. The client is undefined.
picture-this-44ac48bef9f8df633632a4d202da2379.js:57 Uncaught TypeError: Cannot read property 'client' of undefined
component hbs
<script src="https://js.braintreegateway.com/web/3.81.0/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.81.0/js/hosted-fields.min.js"></script>
<div class="demo-frame" {{did-insert this.setupBraintreeHostedFields}}>
<form action="/" method="post" id="cardForm" >
<label class="hosted-fields--label" for="card-number">Card Number</label>
<div id="card-number" class="hosted-field"></div>
<label class="hosted-fields--label" for="expiration-date">Expiration Date</label>
<div id="expiration-date" class="hosted-field"></div>
<label class="hosted-fields--label" for="cvv">CVV</label>
<div id="cvv" class="hosted-field"></div>
<label class="hosted-fields--label" for="postal-code">Postal Code</label>
<div id="postal-code" class="hosted-field"></div>
<div class="button-container">
<input type="submit" class="button button--small button--green" value="Purchase" id="submit"/>
</div>
</form>
</div>
component class
import Component from '#glimmer/component';
import { action } from '#ember/object';
import { inject as service } from '#ember/service';
import { tracked } from '#glimmer/tracking';
import { braintree } from 'braintree-web';
export default class CardPaymentComponent extends Component {
#action
setupBraintreeHostedFields() {
alert('booh');
var form = document.querySelector('#cardForm');
var authorization = 'sandbox_24nzd6x7_gyvpsk2myght4c2p';
braintree.client.create({
authorization: authorization
}, function(err, clientInstance) {
if (err) {
console.error(err);
return;
}
createHostedFields(clientInstance);
});
function createHostedFields(clientInstance) {
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {
'font-size': '16px',
'font-family': 'courier, monospace',
'font-weight': 'lighter',
'color': '#ccc'
},
':focus': {
'color': 'black'
},
'.valid': {
'color': '#8bdda8'
}
},
fields: {
number: {
selector: '#card-number',
placeholder: '4111 1111 1111 1111'
},
cvv: {
selector: '#cvv',
placeholder: '123'
},
expirationDate: {
selector: '#expiration-date',
placeholder: 'MM/YYYY'
},
postalCode: {
selector: '#postal-code',
placeholder: '11111'
}
}
}, function (err, hostedFieldsInstance) {
var tokenize = function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (err, payload) {
if (err) {
alert('Something went wrong. Check your card details and try again.');
return;
}
alert('Submit your nonce (' + payload.nonce + ') to your server here!');
});
};
form.addEventListener('submit', tokenize, false);
});
}
}
}
package.json
...
"ember-cli": "^3.25.2",
"braintree-web": "^3.81.0",
...
** Final Solution **
NPM braintree-web not required. Component class does not have access to the Braintree Window object. Move the tags to the app/index.html as outlined in the accepted answer.
component hbs
<article class="rental">
<form action="/" method="post" id="cardForm">
<label class="hosted-fields--label" for="card-number">Cardholder Name</label>
<div id="card-holder-name" class="hosted-field payment"></div>
<label class="hosted-fields--label" for="card-number">Email</label>
<div id="email" class="hosted-field payment"></div>
<label class="hosted-fields--label" for="card-number">Card Number</label>
<div id="card-number" class="hosted-field payment"></div>
<label class="hosted-fields--label" for="expiration-date">Expiration Date</label>
<div id="expiration-date" class="hosted-field payment"></div>
<label class="hosted-fields--label" for="cvv">CVV</label>
<div id="cvv" class="hosted-field payment"></div>
<label class="hosted-fields--label" for="postal-code">Postal Code</label>
<div id="postal-code" class="hosted-field payment"></div>
<div class="button-container">
<input type="submit" class="button" value="Purchase" id="submit"/>
</div>
</form>
</article>
<script>
var form = document.querySelector('#cardForm');
var authorization = 'sandbox_24nzd6x7_gyvpsk2myght4c2p';
braintree.client.create({
authorization: authorization
}, function(err, clientInstance) {
if (err) {
console.error(err);
return;
}
createHostedFields(clientInstance);
});
function createHostedFields(clientInstance) {
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {
'font-size': '1.2em',
'font-family': 'courier, monospace',
'font-weight': 'lighter',
'color': '#ccc'
},
':focus': {
'color': 'black'
},
'.valid': {
'color': '#8bdda8'
}
},
fields: {
number: {
selector: '#card-number',
placeholder: '4111 1111 1111 1111'
},
cvv: {
selector: '#cvv',
placeholder: '123'
},
expirationDate: {
selector: '#expiration-date',
placeholder: 'MM/YYYY'
},
postalCode: {
selector: '#postal-code',
placeholder: '11111'
}
}
}, function (err, hostedFieldsInstance) {
var tokenize = function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (err, payload) {
if (err) {
alert('Something went wrong. Check your card details and try again.');
return;
}
alert('Submit your nonce (' + payload.nonce + ') to your server here!');
});
};
form.addEventListener('submit', tokenize, false);
});
}
</script>
You can use Braintree SDK via either the direct script tag or using the npm module with the help of ember-auto-import. In your case, you are using both.
For simplicity, let's use the script tag to inject the SDK. The issue in your snippet is that you are trying to load the script tag inside a component handlebar file. the handlebars (.hbs file) cannot load scripts using a <script> tag. We need to move the script tag to the index.html file present inside the app folder. This will load the SDK properly to be used inside a component.
app/index.html:
<body>
...
<script src="https://js.braintreegateway.com/web/3.81.0/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.81.0/js/hosted-fields.min.js"></script>
{{content-for "body-footer"}}
</body>
Once you inject the SDK properly, you can use the braintree window object without any issue.

iOnic list not refreshing after adding a new item to the list using web service

We have a iOnic based project and during check out users can add new address to their account.
This is what my controller file look like
$scope.addAddress = function() {
$scope.showLoading();
addressService.addUserAddress($scope.userDetails.userID, $scope.addAddressdata.houseNo, $scope.addAddressdata.street, $scope.addAddressdata.AddDesc, $scope.addAddressdata.LID)
.success(function(response) {
console.log(response);
$scope.hideLoading();
$scope.closeModal();
$scope.getAllAddress();
});
};
$scope.getAllAddress = function() {
addressService.getAllLocations()
.success(function(response) {
$scope.locations = response;
$scope.hideLoading();
});
};
And this is what my services file look like
function() {
"use strict";
var myApp = angular.module('jobolo');
myApp.service('addressService', ['$http', 'appVariableService', function($http, appVariableService) {
var addressService = this;
addressService.getAllLocations = function() {
var data = {
appid: appVariableService.get('appId')
};
return $http.post(appVariableService.get('baseURL') + 'useraddress/getMyLocation', data);
};
addressService.getUserAddress = function(userId) {
return $http.get(appVariableService.get('baseURL') + 'useraddress/myaddress/' + userId, {cache:false});
};
addressService.addUserAddress = function(userId, houseNo, street, adddesc, lid) {
var data = {
appid: appVariableService.get('appId'),
userid: userId,
houseno: houseNo,
street: street,
adddesc: adddesc,
lid: lid,
};
return $http.post(appVariableService.get('baseURL') + 'useraddress/adAdd' , data);
};
}]);
})();
When I add a new address it does add to the database but isn't showing in list. I tried adding $scope.refreshList(); to the code too. When I log out and come back it does show up. Thank you for your help in advance
View Codes are
<ion-view class="main-content">
<ion-nav-buttons side="secondary">
<button menu-toggle="right" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<div class="bar bar-subheader">
<h2 class="title">Select Address</h2>
</div>
<ion-content class="has-subheader" scroll="true" overflow-scroll="true" style="bottom:57px">
<div class="list">
<ion-radio
ng-model="data.selectedAddress"
ng-value="address"
ng-repeat="address in userAddresses"
class="radio-nowrap"
>
House No. {{address.HouseNo}}, {{address.Street}}, {{address.AddDesc}}, {{address.AreaName}}, {{address.City}}
</ion-radio>
</div>
<!-- <div class="row">
<div class="col location-form">
<button class="button" type="button" ng-click="openModal()">Add New Address</button>
</div>
</div> -->
</ion-content>
<div class="row" style="position: absolute;bottom: 0;padding:0">
<div class="col location-form">
<button class="button" type="button" ng-click="openModal()">Add New Address</button>
</div>
<div class="col location-form">
<button class="button" type="button" ng-disabled="!data.selectedAddress" ng-click="selectAddress(data.selectedAddress)">Select Address</button>
</div>
</div>

Django. How to show and hide DIV based on the selection of the dropdown menu?

I have a dropdown menu and I want to show and hide DIVs based on the selection of that dropdown menu. I have duplicated fields in templates because I do not know the better way to handle, so if someone can suggest me simpler way to code, I will appreciate it.
The code I wrote is below
Template(html)
<div id="pack-method" class="col-sm-30">
{{ form.item_packmethod|as_crispy_field }}
</div>
<div id="hidden2-1">
<div class="col-sm-20">
{{form.pallet_count|as_crispy_field}}
</div>
<div class="col-sm-20">
{{form.pallet_width|as_crispy_field}}
</div>
<div class="col-sm-20">
{{form.pallet_height|as_crispy_field}}
</div>
</div>
<div id="hidden2-2">
<div class="col-sm-20">
{{form.pallet_count|as_crispy_field}}
</div>
<div class="col-sm-20">
{{form.pallet_width|as_crispy_field}}
</div>
<div class="col-sm-20">
{{form.pallet_height|as_crispy_field}}
</div>
<div class="col-sm-20">
{{form.pallet_depth|as_crispy_field}}
</div>
</div>
<script type="text/javascript">
$('#hidden2-1').css({
'display': 'none'
});
$('#hidden2-2').css({
'display': 'none'
});
$('#pack-method').on('change', function() {
if (this.value === 'Pallet') {
$('#hidden2-1').show();
$('#hidden2-2').hide();
}
else if ($(this).val() == 'Rack') {
$('#hidden2-1').hide();
$('#hidden2-2').show();
}
else if ($(this).val() == 'Box') {
$('#hidden2-1').hide();
$('#hidden2-2').show();
}
else {
$('#hidden2-1').hide();
$('#hidden2-2').hide();
}
});
</script>
Forms.py
BLANK_CHOICE = (('', '----------'),)
PALLET = 'Pallet'
RACK = 'Rack'
BOX = 'Box'
PACK_TYPE = (
(PALLET, 'Pallet'),
(RACK, 'Rack'),
(BOX, 'Box'),
)
item_packmethod = forms.ChoiceField(label="Pack Method", choices = BLANK_CHOICE + PACK_TYPE,required=False)
I have solved the problem.
For those who might be interested, I changed
$('#pack-method').on('change', function() {
if (this.value === 'Pallet') {
$('#hidden2-1').show();
$('#hidden2-2').hide();
}
...
}
to
$('select').on('change', function() {
var a = $(this).val();
if (a === 'Pallet') {
$('#hidden2-1').show();
$('#hidden2-2').hide();
}
...
}

{{bindAttr }} {{action}} [Object] Has no method replace

when ember.js tries to render my template containing the following bindAttr. the following exception is thrown in handlebars.js
Uncaught TypeError: Object [object Object] has no method 'replace' handlebars.js:848
bind attr tag:
<div class="postWrapper" {{bindAttr style="display:none"}}>
Update
this also happens when i use the action helper
<div {{action Toggle}} class="btn pull-right">
<i class="postToggler icon-chevron-down " ></i>
</div>
Update Full Code
Template
<script type="text/x-handlebars" data-template-name="Composer">
<div class="postWrapper">
<div class="postContentWrapper" {{bindAttr style="controller.display"}}>
<div class="row-fluid">
<div class="pull-left span10">
To :
<input id="test2" type="text" style="margin-top: 7px;width:90%" />
</div>
<div {{action Toggle}} class="btn pull-right">
<i class="postToggler icon-chevron-down " ></i>
</div>
</div>
<div class="row-fluid" style="height:100%" >
<div id="wmd-button-bar" style="width:48%;display:inline-block" ></div>
<div class="pull-right">
<a>Hide preview</a>
</div>
<div class="wmdWrapper" style="height:80%">
<div class="wmd-panel" style="vertical-align: top;">
<textarea class="wmd-input" id="wmd-input" style="height: 100%;"></textarea>
</div>
<div id="wmd-preview" class="wmd-preview pull-right"></div>
</div>
<br />
</div>
<div class="row-fluid">
<div class="span6 ">
<p>
Tags :
<input id="test" type="text" style="width:80%"/>
</p>
</div>
<div class="span2 pull-right">
<button id="btnSubmitPost" class="btn btn-success pull-right">{{controller.buttonText}}</button>
<button id="btnCanelPost" class="btn btn-warning pull-right">Cancel</button>
</div>
</div>
<div class="row-fluid">
</div>
</div>
</div>
</script>
View and render
/*
MODES
NEW
REPLY
*/
Thoughts.ComposerController = Ember.Object.extend({
mode: 2,
visible: false,
messageContent: "",
buttonText: function () {
switch (this.get("mode")) {
case 1: return "Post";
case 2: return "Reply";
}
}.property(),
display: function () {
if (this.get("visible")) {
return 'display:block';
} else
return 'display:none';
}.property(),
Toggle: function(){
console.log('Helllo');
}
});
Thoughts.ComposerController = Thoughts.ComposerController.create();
Error Information
object dump
string: "data-ember-action="1""
__proto__: Object
constructor: function (string) {
toString: function () {
__proto__: Object
Crashes on the replace method, because the method replace is undefined
Handlebars.Utils = {
escapeExpression: function (string) {
// don't escape SafeStrings, since they're already safe
if (string instanceof Handlebars.SafeString) {
return string.toString();
} else if (string == null || string === false) {
return "";
}
if (!possible.test(string)) { return string; }
----> return string.replace(badChars, escapeChar);
},
So first of all you need to define only need to define the controller. You don't have to create an instance. Ember will do it for you when application initialize.
If you define a property that is observing another in other words its value depends on another, you need this to specify as parameter to property helper.
Thoughts.ComposerController = Ember.Controller.extend({
mode: 2,
visible: false,
messageContent: "",
buttonText: function () {
switch (this.get("mode")) {
case 1: return "Post";
case 2: return "Reply";
}
}.property('mode'),
display: function () {
return 'display:' + this.get('visible') ? 'block' : 'none';
}.property('visible'),
Toggle: function () {
this.toggleProperty('visible');
this.set('mode', this.get('mode') == 2 ? 1 : 2);
}
});
Template itself seems valid.
You can get this working by creating a composer route like this:
this.route('composer');
or by rendering it in another template like this:
{{render 'composer'}}
That should be answer to your question. BUT
Wouldn't be better to use {{if}} helper for showing some content inside of template based on a condition?
i finally found some time to work on this again.
all i did was replace the ember and handlebars js files, and the code is working fine now thanks