In our polymer1.0 component, we had this:
attached: function ()
{
var something=this.getComputedStyleValue("--flxs-" + prop)
this.async(function()
{
// do some work here.
});
}
In 2.0, both this.getComputedStyleValue this.async is not defined.
Any idea what is the alternative?
Polymer.Async seems like the alternate to this.async.
For getComputedStyleValue you can try StyleGather, but i doubt it'll work.
Otherwise, LegacyMixin contains all the old methods.
Related
I'm trying to grab the base name of each html file that passes through a stream. The code here obviously doesn't work because _base is no longer in scope. It seems like there should be a really easy way to do this, or maybe there's something built into gulp-ejs that I don't know about. Thoughts?
gulp.task('html', function () {
return gulp.src('app/*.html')
.pipe(tap(function(file, t){
var _base = path.basename(file.path, '.html');
})
.pipe($.ejs(require('./app/'+_base+'.json')))
});
Can't you just declare _base above the return statement?
gulp.task('html', function () {
var _base;
return gulp.src('app/*.html')
.pipe(tap(function(file, t){
_base = path.basename(file.path, '.html');
})
.pipe($.ejs(require('./app/'+_base+'.json')))
});
You cannot access the filename like that because you are out of the scope of the running stream. What you need to do is use the filename in your tap or use through2. What are you trying to achieve specifically?
I have a Polymer element of which the public API should allow to bind to a function which the user can define, i.e. it should allow to pass in a function implementation. I have tried quite a few approaches but only 1 worked. Now I'm wondering if this is the proper / correct way or not.
To rephrase: what is the proper way to bind a function as part of a dom-module's public API? The only way I have this achieved somewhat is as follows:
<dom-module id="channel-search">
<template>
<remote-dropdown
id="dropdown"
label-text="Type channel name"
url='{{_findRecordUrl}}'
url-transformer='{{urlTransformer}}'
result-to-list-transformer='{{resultToListTransformer}}'
class="layout horizontal"
style='width: 100%'>
</remote-dropdown>
</template>
</dom-module>
<script>
(function() {
Polymer({
is: 'channel-search',
properties: {
_findRecordUrl: {
type: String,
value: 'http://127.0.0.1:9292/epics-boot-info.psi.ch/find-channel.aspx'
}
},
/*
* Here in the attached function, I define the methods which will then be bound to
* the respective properties of the remote-dropdown element
*/
attached: function() {
this.urlTransformer = function(baseUrl, currentInput) {
return baseUrl + '/' + currentInput;
};
this.resultToListTransformer = function(findRecordList) {
var responseList = findRecordList.map(function(res) {
return res.Channel;
});
return responseList;
};
}
});
})();
</script>
So, I needed to define the functions in the attached callback in order for them to be properly bound to the remote-dropdown element's public API.
I hoped it would be a bit clearer / easier, maybe like so:
<script>
(function() {
Polymer({
is: 'channel-search',
properties: {
_findRecordUrl: {
type: String,
value: 'http://127.0.0.1:9292/find-channel.aspx'
}
},
urlTransformer: function(baseUrl, currentInput) {
return baseUrl + '/' + currentInput;
};
resultToListTransformer: function(findRecordList) {
var responseList = findRecordList.map(function(res) {
return res.Channel;
});
return responseList;
};
});
})();
</script>
i.e. simply define the function implementation as part of the element's definition and then bind those to the embedded remote-dropdown element. However, that never seemed to work as I thought it would (also not variations thereof) - surely also because of my limited knowledge of Polymer/Javascript internals.
My question is: is the solution using the attached callback the proper way to achieve what I am trying to do? If not, what would be the correct way to implement this?
You can probably do that using computed properties or computed bindings. Your first answer looks like a variation of the latter.
Issue:
I have a lot of small helper functions that don't necessarily need to live in a component(or maybe they can but they will make that component bloated with a lot of code).My lazy side just wants to just let those all just be some sort of global functions that the components can call.I really want to make good ReactJs code.
Question:
What are the best practices in terms of global helper functions in Reactjs? Should I force them into some sort of component or just shove them into the other components?
Basic Example:
function helperfunction1(a, b) {
//does some work
return someValue;
}
function helperfunction2(c, d) {
//does some work
return someOtherValue;
}
function helperfunction3(e, f) {
//does some work
return anotherValue;
}
function helperfunction4(a, c) {
//does some work
return someValueAgain;
}
var SomeComponent =
React.createClass({
//Has bunch of methods
//Uses some helper functions
render: function () {
}
});
var SomeOtherComponent =
React.createClass({
//Has bunch of methods
//Uses some helper functions
render: function () {
}
});
You can export multiple functions from a file, no React needed per se:
Helpers.js:
export function plus(a, b) {
return a + b;
}
export function minus(a, b) {
return a - b;
}
export function multiply(a, b) {
return a * b;
}
export function divide(a, b) {
return a / b;
}
You can then import the functions you need:
import { multiply, divide } from './Helpers'
You can use a module-bundling tool like Webpack or Browserify for that.
Put your reusable functions in a CommonJS module.
Do not use Mixins, they will probably be deprecated in next versions of React as there's no standard way to declare mixins in React with ES6 syntax and they prefer to wait for ES7 that will probably standardize mixins. And there's no point coupling your reusable code to React unless it uses React lifecycle's methods.
You can use modulejs.
or you can use mixins (https://facebook.github.io/react/docs/reusable-components.html#mixins)
Sample for mixins: https://jsfiddle.net/q88yzups/1/
var MyCommonFunc = {
helperFunction1: function() {
alert('herper function1');
},
doSomething: function(){
alert('dosomething');
}
}
var Hello = React.createClass({
mixins: [MyCommonFunc],
render: function() {
this.doSomething();
return <div onClick={this.helperFunction1}>Hello {this.props.name} </div>;
}
});
React.render(<Hello name="World" />, document.getElementById('container'));
Just another option, if you don't want to split into a separate module, you could create a private method in your parent component like below and use freely within this component or pass to the child components via props..
var YourComponent = React.createClass({
globalConfig: function() {
return {
testFunc: function () {
console.log('testing...');
},
};
}(),
......
render: function() {
this.globalConfig.testFunc(); // use directly
<ChildComponent testFunc={this.globalConfig.testFunc} /> // pass to child
.....
All untested, but that's the idea...
Use a React context to do something like this. It's built for this exact use case;
Doc: https://reactjs.org/docs/context.html
react can be avoided altogether, like Michiel says
though a slight improvement would be to put all those pure js functions in a single fle then connect it to your html start page and the functions will be available everywhere:
just with a
<script src='./global-func.js' ></script>
its a dirty hack but it works ;)
you wont have to import the file into every component class you make
I want to do something like this (but obviously not this exactly, because this function doesn't work this way)
angular.bootstrap( $("#myelement"), ['myModule'], {foo: bar} );
I want to pass in a configuration object, since we may want to have more than one instance of the app on a page, with different settings, etc. All I can think of are ugly workarounds. I'm thinking the best thing would be to override an "Options" service of my own making, but I still can't figure out the proper way to do that (tersely).
Thanks in advance!
How about you try something like this:
angular.module('configFoo', []).run(function() {});
angular.module('configBar', []).run(function() {});
angular.bootstrap(myEl, ['myModule', 'configFoo']);
angular.bootstrap(myOtherEl, ['myModule', 'configBar']);
http://docs.angularjs.org/api/angular.Module for all available module methods (you're probably only interested in .run() and .config())
Here is a working code:
http://jsfiddle.net/x060aph7/
angular.module('myModule', [])
.controller('myController', function($scope,myConfig) {
$scope.name = 'inst '+myConfig.foo;
})
;
var aConfig = [{foo:1},{foo:2},{foo:3}];
aConfig.forEach(function(config){
angular.module('fooConfig',[]).value('myConfig', config);
angular.bootstrap(getDiv(), ['myModule','fooConfig']);
});
function getDiv(){
var mDiv = document.createElement('div');
mDiv.setAttribute('ng-controller','myController');
mDiv.innerHTML = '<span>{{name}}</span>';
document.body.appendChild(mDiv);
return mDiv;
}
The following example helped us out bootstrapping a widget to a page. First a div is made - with a bit of jQuery - for the widget to load a template with an ng-include, it is controlled by WidgetLogoController. Next a module WidgetConfig is created that holds the widget's configuration.
$('#pageWidget').html(`<ng-include src="'/dist/templates/widgetLogo.html'"></ng-include>`)
.attr('ng-controller','WidgetLogoController');
var widgetConfig = {
'widgetId': data.pageWidgetId,
'areaId': data.area,
'pageId': data.pageId
};
angular.module('WidgetConfig', []).value('WidgetConfig', widgetConfig);
angular.bootstrap(document.getElementById('pageWidget'), ['Widget', 'WidgetConfig']);
Widget module includes the WidgetConfig configuration but also has a spot for it own in CONFIG:
(function (window, angular) {
'use strict';
window.app = angular.module('Widget', ['ngFileUpload', 'WidgetConfig'])
.constant('CONFIG', {
BASE_URL: 'http://osage.brandportal.com/'
});
})(window, angular);
WidgetController can access CONFIG and WidgetConfig.
(function (app) {
'use strict';
app.controller('WidgetLogoController', ['CONFIG', 'WidgetConfig',
function(CONFIG, WidgetConfig){
console.log('---WidgetLogoController');
console.log('CONFIG', CONFIG);
console.log('WidgetConfig', WidgetConfig);
}]);
}(app));
What about:
Load config and than load angular:
angular.element(document).ready(() => {
$.get('config', // url to my configuration
{},
function (data) {
window.config = data;
angular.bootstrap(document, ['myApp']);
}
);
});
Access the config:
angular.module('myApp').run(myAppRun);
function myAppRun($window) {
$window.config; // here I have config
}
JavaScript
$.each(['#clk','#clk1'], function()
{
$(this).click(function () {
alert("click")
});
});
HTML
click me
click me
No alert box when the link is clicked.
UPDATE:
I have more than 1 id. I have shown only one to simplify the problem.
You will have to use String.toString() to get the value of the String object.
It´s not clear why you would need an array of selectors but here are two solutions;
Your solution using String.toString();
// Array of strings to be used as element selectors.
var selectors = ['#element1', '#element2'];
// Using $.each()
$.each(selectors, function() {
// String.toString() returns the value of the String object.
var $this = $(this.toString());
$this.click(function () {
console.log('Clicked element(1) =', this.id || this); // DEBUG
});
});
Alternative solution using String.join();
// Using String.join()
$(selectors.join(',')).click(function(event) {
event.preventDefault(); // This is to not follow the link
// Notice that "this" now referes to the current/clicked element
// and not any string value from the "selectors" array.
console.log('Clicked element(2) =', this.id || this); // DEBUG
});
See my demo.
If you don´t really need the array of selectors I would recommend a simple multiple selector like this;
$('#element1, #element2').click(function() { ... });
You could further simplify it to:
$("#clk").click (function () {
alert("click");
});
Firstly, why are you using a foreach construct when iterating over an id? When you are using and id, there is supposed to be EXACTLY ONE element with the given id. So, this should be fine:
$("#clk").click(function() {
alert("click");
});
Secondly, each iterates over an array, your array being #clk. Just the string, nothing else. All your function gets is two parameters: 0' (the index of the element) and the string#clk` (the value at that index). The string IS NOT resolved to a JS object.
IMO, the cleanest way to solve your problem statement would be:
$("a[id^='clk']").click(function () {
alert("click");
});
The ^= selector would select all anchors whose id starts with 'clk' and bind the click function to all of those. You can read more about this selector here