Using angular translate with custom directive - angular-directive

Currently I am creating my own directive using the angular translate. As a tooltip for the image I am using some translation. When I am switching the language, the translation text stays the same, when it should change. I think, that the directive got compiled once with the current translation value, but I don't know how to get it updated any time I switch my language (some kind recompile).
Below my directive code.
'use strict';
angular.module('HomeModule')
.directive("headerName", ["tabService", "imageService", "$translate", "$filter", function(tabService, imageService, $translate, $filter){
var directive = {};
directive.restrict = 'E';
directive.template = '<div class="vcenter"><img ng-src="' + imageService.getImageByKey('arrowLeftSrc') + '" height="20px" tooltip-class="custom-tooltip" tooltip="' + $filter('translate')('RETURN') + '" tooltip-placement="bottom" tooltip-popup-delay="500" class="return-arrow"/></div>' +
'<div class="vcenter"><i class="fa fa-angle-down fa-2x"/></div>';
directive.scope = {}
return directive;
}]);

In short the solution is: translate-attr-tooltip="RETURN".
Don't use a $filter in your directive template, but the angular-translate directive translate-attr-* (https://angular-translate.github.io/docs/#/api/pascalprecht.translate.directive:translate).
Here is a JSFiddle to play around - http://jsfiddle.net/ku326j6p/2/

Related

How can I use "<nuxt-link>" in content rendered with "v-html"?

I have a utilities plugin for Nuxt.js that I created with a method to parse hashtags and mentions and replace them with <nuxt-link>. I am then using v-html to inject the converted data back into the template. My issue is that the <nuxt-link> are not being parsed with v-html.
import Vue from 'vue';
Vue.mixin({
methods: {
replaceMentions(data) {
// Tags
const tagRegEx = /\[#tag:[a-zA-Z0-9_-]*\]/g;
let tagMatch;
while ((tagMatch = tagRegEx.exec(data)) !== null) {
const tag = Array.from(tagMatch[0].matchAll(/\[#tag:(.*?)\]/g));
data = data.replace(tag[0][0], '<nuxt-link to="/search?q=' + tag[0][1] + '">#' + tag[0][1] + '</a>');
};
// Users
const userRegEx = /\[#user:[a-zA-Z0-9_-]*\]/g;
let userMatch;
while ((userMatch = userRegEx.exec(data)) !== null) {
const user = Array.from(userMatch[0].matchAll(/\[#user:(.*?)\]/g));
data = data.replace(user[0][0], '<nuxt-link to="/users/' + user[0][1] + '">#' + user[0][1] + '</>');
};
return data;
}
}
});
Does anyone have any tips for how I could make these work as proper nuxt compatible links? I already tried using <a> and it works fine, I would just prefer to utilize proper nuxt compatible links.
I think the discussion here basically answers the question: https://github.com/nuxt-community/modules/issues/185
Summarized, there are two options:
Render the HTML with a full Vue build and then attach the rendered node.
(Preferred) Find the links in the HTML and make them call router push instead of their default action.

What is the mechanism of calling a function from a template in Vue js

I am trying to learn Vue.js. I am following a tutorial on this site https://scrimba.com/p/pZ45Hz/c7anmTk. From here I am not getting something clear.
Here is the code below and my confusion as well :
<div id="app">
<wizard :name="harry" :cast="oculus_reparo" ></wizard>
<wizard :name="ron" :cast="wingardium_leviosa"></wizard>
<wizard :name="hermione" :cast="alohomora" ></wizard>
</div>
// emojify returns the corresponding emoji image
function emojify(name) {
var out = `<img src="emojis/` + name + `.png">`
return out
}
// cast returns a spell (function) that decorates the wizard
function cast(emoji) {
var magic = emojify("magic")
return function (wizard) {
return wizard + " " + magic + " " + emoji + " " + magic
}
}
Vue.component("wizard", {
props: ["name", "cast"],
template: `<p v-html="cast(name)"></p>`
})
var app = new Vue({
el: "#app",
data: {
harry : emojify("harry" ),
ron : emojify("ron" ),
hermione : emojify("hermione")
},
methods: {
// oculus_reparo returns a spell (function) that repairs glasses
oculus_reparo: cast(emojify("oculus-reparo")),
// wingardium_leviosa returns a spell (function) that levitates an object
wingardium_leviosa: cast(emojify("wingardium-leviosa")),
// alohomora returns a spell (function) that unlocks a door
alohomora: cast(emojify("alohomora"))
}
})
So far what I have got is that, I have created a component named wizard which takes two properties - name and cast. name is getting the value from data, and so far I understand that cast is calling the method with a parameter.
So both of them should return their specific image. My first confusion: Where does wizard come from and how is it showing the data.name image? If it is because of the method call in the template then why does emoji return another image?
I think the example is unnecessarily complex for the ideas you're looking to learn.
wizard is being globally registered with Vue by Vue.component("wizard", ...). When Vue interprets each wizard call in the template it will replace it with <p v-html="cast(name)"></p> which is set in the wizard component definition. Here name gets mapped to the property that is set via :name=. v-html is just saying to render as html the return value of cast(name), here cast is the function property that is passed to the component and not the cast function locally defined. Everything after that happens as you would expect where emojify returns a template literal that is passed to cast, that then returns a function, which combines the emoji and other properties.

Vuejs: How to write directives similar to v-model, for jquery plugins

The v-model directive is limited to input event. but i want it to support jquery change events too, so that i can use jquery plugins like bootstrap-toggle without having to write separate codes to manipulate those fields.
The main challenge i'm facing is how to update the value bound to the element, on jquery change event. I tried triggering input event on change event is fired, but it didn't work.
Here is what i'm trying to achieve:
HTML:
<input id="dayparting_switch" v-observe="options.dayparting" v-model="options.dayparting" :cheked="options.dayparting" data-off="Disabled" data-on="Enabled" data-toggle="toggle" type="checkbox">
Custom directive:
Vue.directive('observe', {
bind: function(el, bind, vnode) {
$(el).is(':checkbox') ? $(el).prop('checked', !!bind.value) : $(el).val(bind.value);
$(el).change(function() {
var newVal = $(el).is(':checkbox') ? $(el).prop('checked') : $(el).val();
// Here comes problem: how to set new value to options.dayparting ?
// 1) bind.value = newVal won't trigger any update
// 2) this.dispatchEvent(new Event('input')) also doesn't work
// 3) Only quirky way of doing this is to parse bind.expression to get object and keys and then use Vue.set
var lastDot = bind.expression.lastIndexOf('.');
var object = bind.expression.substring(0, lastDot);
var key = bind.expression.substr(lastDot+1);
Vue.set(eval('vnode.context.' + object), key, newVal);
});
}
});
The above method actually worked for me, but i think it is not a perfect method. for eg, it won't work for v-observe="options[option_name]"
Is there any simple or standard method to achieve this ?
In Vue 1, it was possible to write two-way binding directives (like v-model), but in Vue 2, you do it with components.
Have a look at the Wrapper Component Example.

Razor template editor doesn't like my Knockout attr binding syntax

I have an Knockout attr binding that is working perfectly well:
<a data-bind="attr: { href: 'Action?destination=' + '#Model.Property' + '&entityId=' + Id }">Select</a>
However, the syntax highlighting in Visual Studio is throwing an 'Unterminated String Constant' error once any model property in inserted into the href string.
I've experimented with '#()' and '#:', but nothing seems to make the editor happy.
I had a similar issue where I wanted to pass controller action URLs (provided by the UrlHelper instance of the Razor view) to my viewmodel functions to be used later in jQuery AJAX calls.
The following markup works in the browser, but gives syntax highlighting in Visual Studio:
<button data-bind="click: function (data) { someFunction(data, '#Url.Action("SomeAction", "SomeController")') }">Action!</button>
The syntax highlighting can be suppressed by changing the above to the following:
<button data-bind="#("click: function (data) { someFunction(data, '" + Url.Action("SomeAction", "SomeController") + "') }")">Action!</button>
Why not just use a regular Html.ActionLink?
#Html.ActionLink("Action", "Select", new { destination = Model.Property, entityId = Model.Id });

ASP.NET MVC 4 Html.Action with JavaScript variable

I want to use javascript variable inside MVC Action route values. I referred this Stackoverflow post and the answer given there is working fine.
But i don't want to write an extra javascript function to achieve this. Without writing extra function, Is there any other way to do it. I meant, is there any new added feature in MVC4 for this? As the example in that link is for MVC 2.
self.EditUrl = ko.computed(function () {
return "#Url.Action(Actions.User_Update, Controllers.User, new { Id = self.Id() } )";
});
It is still the same case with MVC 4. You cannot mix client code and server code. I don't think it would even be possible in the future. Having said that, what you're trying to do is achievable. You can always write the url in a hidden field:
<input type="hidden" id="userUpdateUrl" value="#Url.Action("User_Update","User")"/>
Then use that on your client-side binding:
self.EditUrl = ko.computed(function () {
return $("#userUpdateUrl").val() + "?" + self.Id();
});