I have a player class and viewmodel
class Player
constructor: ->
#boat = ko.observable null
class Boat
constructor: (#id) ->
class ViewModel
player: ko.observable
in html
<div data-bind="if: player">
<div data-bind="template: {name: 't_me', data: player}"></div>
</div>
<script type="text/html" id="t_me">
<span>player boat
<span data-bind="if: boat()">
<b data-bind="text: boat().id"></b>
</span>
</span>
</script>
now in script i try to set boat to plyer
vm = new ViewMode()
ko.applyBindings vm
vm.player new Player()
vm.player.boat new Boat(1)
And I can't make View react on this changes any ideas?
The only problem I see with your code is lack of parens on the vm.player observable. (assuming that vm = new ViewMode() is a typo)
I believe the last line should be: vm.player().boat new Boat(1)
Related
In Vue.js I can define named slots for my components, besides my default slot:
<article>
<header>
<slot name="header">
<h2>Default heading</h2>
</slot>
</header>
<slot/>
</article>
and then use it like this:
<template>
<FooArticle v-for="item in items">
<template #heading>
<h3>{{item}} Heading</h3>
</template>
<p>Just content</p>
</FooArticle>
</template>
<script>
export default {
name: 'App',
components: {
FooArticle
},
data() {
return {
items: ['First', 'Second']
}
}
}
</script>
Is this possible with Neos Fusion, to create a mechanism like this?
Yes this is possible, as you can use the #path decorator to overwrite a property of the wrapper element.
First you define your props and then output them in the renderer.
prototype(Foo.Components:Article) < prototype(Neos.Fusion:Component) {
heading = afx`<h2>Default heading</h2>`
content = ''
renderer = afx`
<article>
<header>
{props.heading}
</header>
{props.content}
</article>
`
}
Then you want to override these "slots" (props) from the outside with the #path decorator. The whole element the decorator is defined on will override the specified prop "heading" of the wrapping element.
prototype(Foo.Site:Home) < prototype(Neos.Fusion:Component) {
items = ${['First', 'Second']}
renderer = afx`
<Neos.Fusion:Loop items={props.items}>
<Foo.Components:Article>
<Neos.Fusion:Fragment #path="heading">
<h3>{item} heading</h3>
</Neos.Fusion:Fragment>
<p>just some content</p>
</Foo.Components:Article>
</Neos.Fusion:Loop>
`
}
FYI, we use a Neos.Fusion:Fragment object to define the path decorator, so the fragment does not render any additional markup like an enclosing <div>. In this simple case, where we only want to render a single element into the slot, we could have omitted the fragment and just set the #path="heading" directly to the <h3>.
Working example in FusionPen
Fusion AFX Docs
Neos Fusion Docs
This may be a basic question, but I'm struggling. Essentially I have a livewire component that updates an array of flight information that a user enters. Whenever the components get rerendered, the flatpickr functionality stops working entirely. I presume this is because the javascript to initialize the component on that field is not running. What is the best practice to ensure these get rerendered with the appropriate javascript to enable the functionality.
Here's my blade snippet which renders fine on the initial load, but whenever a change to the data occurs, the page re-renders all the flights in the array, but the flatpickr functionality does not work anymore.
<form>
#foreach($flights as $i => $f)
<label
x-data
x-init="flatpickr($refs.input, {
dateFormat: 'Y-m-d H:i',
altInput: true,
altFormat: 'F j, Y h:i K',
enableTime: true,
})">
<div class="form-label">Arrival Time</div>
<div class="relative">
<input type="text"
wire:model="flights.{{ $i }}.ArrivalTime"
wire:key="fl{{ $i }}arrtime"
data-input
x-ref="input"
placeholder="Arrival Time"
value="{{ $f['ArrivalTime']}}"
name="flights[{{ $i }}][ArrivalTime]"
id="ArrivalTime{{$i}}"
/>
</div>
</label>
#endforeach
</form>
The livewire component is basically this:
class Itinerary extends Component
{
public $itin = null;
public $flights = [];
public function render()
{
return view('livewire.itinerary');
}
}
You need to wrap the input in a <div> like this:
<div wire:ignore>
<!-- Your input here -->
</div>
Source: https://laravel-livewire.com/docs/2.x/alpine-js#ignoring-dom-changes
first time posting so sorry if I mess something up. Below is the code I have tried:
const domPreParse = new JSDOM(incident); //incident is the html fragment I want to parse
const dom = domPreParse.window.document;
const cNameHome = dom.querySelector('[data-type="home-icon"], svg').className;
So cNameHome returns an object with only the first class name. There are multiple class name on the element (e.g. class="class1 class2"). How can I return all the classes in a space separated string preferably.
And this is the code I'm trying to parse:
<div class="sco" data-type="middle">
<div class="clear">
<span class="inc" data-type="home-icon"></span>
<span class="score" data-type="score"> </span>
<span class="inc" data-type="away-icon">
<svg class="inc yellowcard"><use xlink:href="#icon-yellowcard"></use></svg>
</span>
</div>
</div>
Thanks for the help.
The problem was my CSS selectors. I should have used [data-type="home-icon"] > svg.
I'm using slick carousel, and once a div is active I want to open the corresponding description.
Problem I'm having is with this code:
if ($('div').hasClass('active')) {
var title = $(this).attr('title');
$('ul li').removeClass('open');
$(title).addClass('open');
}
What I'm trying to achieve:
Once a div gets class 'active', I want to take its title value, and use it as a id link to list element I want to display(add class to).
Here is a FIDDLE.
Use event handling, not class monitoring.
The slick carousel API has events for this, I believe you want to use the afterChange event to act on the active element after it has been made visible.
Check out the docs and examples, especially the section titled "Events" on Slick page: http://kenwheeler.github.io/slick/
And I think you don't want to use title attribute for this because that is for tooltips. I recommend data-* attributes instead. And element IDs should generally start with a letter and not a number (was required in HTML4 and makes life easier when mapping IDs to JavaScript variables; though if you are using HTML5 I think this requirement is no longer in effect).
HTML
<div id="carousel">
<div data-content-id="content1">
Selector 1 </div>
<div data-content-id="content2">
Selector 2 </div>
<div data-content-id="content3">
Selector 3 </div>
</div>
<ul class="content">
<li id="content1">Content 1</li>
<li id="content2">Content 2</li>
<li id="content3">Content 3</li>
</ul>
JavaScript
$('#carousel').on('afterChange', function(event, slick, currentSlide) {
// get the associated content id
var contentId = $(slick.$slides.get(currentSlide)).data("content-id");
if(contentId && contentId.length)
{
var $content = $("#" + contentId);
$(".content>li").removeClass("open"); // hide other content
$content.addClass("open"); // show target content, or whatever...
}
});
I have found a solution:
$('.slider').on('afterChange', function(event, slick, currentSlide, nextSlide){
var contentId= $(slick.$slides.get(currentSlide)).data('content');
if(contentId)
{
$(".content li").removeClass('open');
$('#' + contentId).addClass('open');
}
});
Working fiddle
When I study the feature of Vue.js's component system. I feel confused when and where should we use this? In Vue.js's doc they said
Vue.js allows you to treat extended Vue subclasses as reusable
components that are conceptually similar to Web Components, without
requiring any polyfills.
But based on their example it doesn't clear to me how does it help to reuse. I even think it complex the logic flow.
For example, you use "alerts" a lot in your app. If you have experienced bootstrap, the alert would be like:
<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<strong>Title!</strong> Alert body ...
</div>
Instead of writing it over and over again, you can actually make it into a component in Vue:
Vue.component('alert', {
props: ['type','bold','msg'],
data : function() { return { isShown: true }; },
methods : {
closeAlert : function() {
this.isShown = false;
}
}
});
And the HTML template (just to make it clear, I separate this from the Vue Comp above):
<div class="alert alert-{{ type }}" v-show="isShown">
<button type="button" class="close" v-on="click: closeAlert()">×</button>
<strong>{{ bold }}</strong> {{ msg }}
</div>
Then you can just call it like this:
<alert type="success|danger|warning|success" bold="Oops!" msg="This is the message"></alert>
Note that this is just a 4-lines of template code, imagine when your app uses lot of "widgets" with 100++ lines of code
Hope this answers..