In the client, I know you can use Template.[template name] to reference a specific template.
How could you get a list of all custom meteor templates included in your app that have been created by you (not meteor or included from a package)?
Building on what Richard said, you can check if the property on the Template object is a template like this:
var templates = [];
for(var key in Template){
if(Blaze.isTemplate(Template[key])){
templates.push( key );
}
}
console.log( templates );
You'd probably have to use a specific naming convention for identifying your own templates.
Just do Object.keys(Template). I attached a screenshot from the console.
Basically meteor creates a class called Template. We can iterate over all the keys in the template class.
Related
Ive looked related posts and couldn't quite find what I was looking for.
So I am build a backend rest api and I have certain tests I am collecting data on. The tests have their own models, and these models are associated with collections (obviously).
So I have a separate controller for each model. Now I have a "job" controller which queries data from each separate test. Now I have a separate script where I store these model objects in an JSON object. I am wondering how I can access these models properly (I am close but cant quite assign properly). Here is the block:
const testMappings = {
'aprobe':aprobe,
'status':status,
//'rxserial':rxserial,
}
Now when I try assignment as follows, where testMappings is the imported script variable:
const testMappings = activeTests.testMappings;
console.log(testMappings['aprobe']);
I get the following output:
Model {aprobe}
I would like to access the actual aprobe object. Also if anyone knows a better way of dynamically assigning these (instead of having bunch of if statements ie if(name == 'aprobe').... do something), it would be much appreciated.
You are probably looking for something like below :
const name = 'aprobe';
Object.keys(testMappings).indexOf(name) > -1 ? testMappings[name] : null
the above should give you: Model {aprobe}
So basically if the key exists in your object then you'd like to fetch the value of that key which would give you your model dynamically.
I am working on angular 4 project, I had a requirement to drag item, So I was using ng2-dragula plugin to do it for me. Now I need to extract data-id attribute from each row after drop to specific position.
dragulaService.drop.subscribe(
(args) =>{
const [bagName, elSource, bagTarget, bagSource, elTarget] = args;
console.log('after', $(bagSource)); // element after the inserted element
});
In $bagSource variable I will get each rows in new order. Say it be
<tr attributes data-id="23"><tr>
<tr attributes data-id="2"><tr>
<tr attributes data-id="32"><tr>
How could I extract data-id from each tr fields. I need to get each id in their new order in an array.
My required result should be [23,2,32];
jquery $(element).attr("data-id") equivalent in angular 4.
Something similiar to jquery $(element).attr("data-id") can be achieved with #ViewChild and some old-fashioned javascript. It would look like:
Use this only when drag zone and table is not related (if it is use #user3263307 answer it's more Angular-friendly). However the best option would be make use of [attr.data-id]="someVariable", but since I don't know your app structure can't help you with implementing this method.
.*html File
<table #tableRef>
<tr attributes [attr.data-id]="23"><tr>
<tr attributes [attr.data-id]="2"><tr>
<tr attributes [attr.data-id]="32"><tr>
</table>
Simply #tableRef is something like template variable which angular will bind with #ViewChild in component file.
*.component.ts
#ViewChild() tableRef: ElementRef;
public getIds() {
if (!this.tableRef|| !this.tableRef.nativeElement)
return;
//assuming that table would have only one `tbody` tag.
let tableBody = this.tableRef.tBodies[0];
if (!tableBody)
return;
// we need to use Array.from, because `.children` returns HTMLCollection<Element>
// type which is not handy to iterate through it.
let childs: Array<HTMLTableSectionElement> = Array.from(tableBody.nativeElement.children);
let arrIds = [];
for(let child of childs) {
if (!(child.nodeName && child.nodeName.toLowerCase() == "tr"))
continue;
arrIds.push(child.dataset.id);
}
}
Please note that it's a bit brutal method for angular since it's best not to interfere into HTML DOM structure. However as long we are only getting data from elements everything should be fine.
Please note that too about using #ViewChild.
Use this API as the last resort when direct access to DOM is needed. Use templating and data-binding provided by Angular instead. Alternatively you can take a look at Renderer2 which provides API that can safely be used even when direct access to native elements is not supported.
Relying on direct DOM access creates tight coupling between your application and rendering layers which will make it impossible to separate the two and deploy your application into a web worker.
From Angular docs link
In angular attributes should be defined like this:-
<tr attributes [attr.data-id]="23"><tr>
And attribute can be accessed using dataset property of Eventtarget object:-
dragulaService.drop.subscribe(
(args) =>{
const [bagName, elSource, bagTarget, bagSource, elTarget] = args;
console.log('id is:', elTarget.dataset.id);
});
I'm having trouble finding the solution for a simple issue I'm currently having when trying to chain an object rendered from express in my handlebars file.
The object I'm trying to chain looks like so:
"generalContentOfferOne": {
"subCopy": {
"en-us": "Test Copy",
"bahasa": "Bergabunglah dalam..."
}
}
In my handlebars file, {{distributorJSON.generalContentOfferOne.subCopy}} renders Object object, which it should.
I have a localization variable I'm also rendering to handlebars. It will either be en-us or bahasa based on route. Anyways, now that I have this localization value, I figured I could use bracket notation to render the dynamic value in the object above. For example:
{{ distributorJSON.generalContentOfferOne.subCopy[{{localization}}] }}
Also tried:
{{ distributorJSON.generalContentOfferOne.subCopy.{{localization}} }}
These aren't working.. I'm guessing handlebars has it's own specific way to chain dynamic values? Or at least I hope so. Thanks for your help!
I couldn't find a default solution for this. So I built a handlebars helper.
Helper:
exports.returnDynamicPropValue = function(object, localization){
return object[localization];
}
Handlebars template:
{{ returnDynamicPropValue distributorJSON.generalContentOfferOne.subCopy localization }}
I am new-ish to jade templates and some of the more complex feature that exist in the templates. As of right now, I am building a mock portfolio site using node and jade. I have a layout that is inherited by all other jade files. The layout has all of the universal site navigation inside of it. I am wanting to highlight what section of the website the user is currently in. I am currently doing this by having a unique js files that will load when the user is in a particular section. This js file will add a class on to the list item in which will add the highlighting to the navigation.
My question, do I need to create and load these js files in order to accomplish this? Is there a better way to get a universal navigation in one template while having a unique highlighter?
If the highlighting does not have functional purposes (e.g. accessibility), or it's done using URI fragments (hashtags), it might be better to leave it to the JS.
If your navigation highlight is per page, you could set it up in nodejs/jade, for example:
app.get('/about', (req, res) => {
var locals = {};
locals.navHighlight = 'about';
res.render('about', locals);
});
And in your jade template you could do something like this:
ul.navigation
li(class=(navHighlight=== 'about' ? 'highlight' : '')) About Me
li(class=(navHighlight=== 'blog' ? 'highlight' : '')) My Blog
Whatever you pass as properties to the locals object of res.render, is available in Jade as variables. And in jade, when using the tag(attr=value, attr2=value,...) format you have access to JS syntax and the exposed variables.
As long as you set a variable (e.g. navHighlight based on which route it enters, you can use that to set the class attribute of the tag. Just make sure to separate the class names with spaces, if you have multiple classes.
I am trying to find the best way to transform a large JSON object into a view model. Previously, I had the model incorporated into the view, which is a bad practice. So, now I have the model being generated inside of a controller. I am using Lodash as a utility library.
My current design plan is to transform the JSON object into a "master" array that is accessible in the controller's scope. The JSON file is being served by Express. ModelService simply gets this file to make it available in the controller.
$scope.arr is the "master" array that I want to use in the view.
I also made the JSON data available for viewing at an external link since it is so large. Here it is.
(function() {
'use strict';
angular
.module('app')
.controller('ModelController', ModelController);
function ModelController($scope, ModelService, _) {
$scope.jsonData = ModelService.getAll();
$scope.getData = function() {
$scope.jsonData.$promise.then(function(data) {
$scope.all = data;
$scope.arr = [];
_.mapValues($scope.all.parent1.clusters, function(cluster) {
$scope.arr.push(cluster.name);
_.mapValues(cluster.subclusters, function(subcluster) {
$scope.arr.push(subcluster.name);
_.mapValues(subcluster.entities, function(entity) {
// map entities
})
});
});
});
};
$scope.getData();
}
})();
This code is just adding cluster and subcluster names to the array. I'd like the subclusters to be mapped to their parent cluster. The idea I have for doing this involves transforming each cluster element into its own array, and then adding the subclusters, and then transforming each subcluster into an array in order to map the entities to them. This seems tedious and inefficient. So, I am looking for a better way to achieve this.
It would be nice if I could add each cluster object to the array in one fell swoop without all the mapping and converting objects to arrays. Is that possible at all?
The wireframe view looks like this. The Flex Cluster Title is the name of the subcluster, and each number inside of them is an entity.
Firstly, I would move this processing into the service. It's easier to test, and keeps your view separated from your models (Controllers, are really more part of the "View" IMO when it comes to Angular especially if you're considering upgrading to Angular 2.0 in the future).
In Angular, I think the appropriate way to solve this, would be to use components (or directives) combined with ng-repeat.
The page template:
<!-- Page template, assume $ctrl is your controller, $ctrl.clusters is the data -->
<cluster ng-repeat = "cluster in $ctrl.clusters"
cluster-data="cluster" >
</cluster>
The cluster directive template:
<!-- Assume $ctrl is the controller for the cluster directive, $ctrl.cluster is the cluster object. -->
<div class="name">{{$ctrl.cluster}}</div>
<div class="subClusterNames"
ng-repeat="subCluster in $ctrl.cluster.subClusters>
{{subCluster.name}}
</div>
You might think that this is mapping your data too closely to the view, but as long as you use components to display your data (ie, don't put it all into one template) I think you'll be fine.