nextjs13.1 The key problem is prompted, but the format is unknown. Many similar answers have been searched, but this presentation method does not seem to be found. Is there a good way to solve it? A warning appears on the console:
next-dev.js?3515:20 Warning: Each child in a list should have a unique "key" prop.
Check the render method of `Links`. See https://reactjs.org/link/warning-keys for more information.
at li
at Links
at div
at footer
at Footer
at div
at Home
at PersistGate (webpack-internal:///./node_modules/redux-persist/es/integration/react.js:39:5)
at Provider (webpack-internal:///./node_modules/react-redux/es/components/Provider.js:13:3)
at MyApp (webpack-internal:///./pages/_app.js:21:11)
at PathnameContextProviderAdapter (webpack-internal:///./node_modules/next/dist/shared/lib/router/adapters.js:62:11)
at ErrorBoundary (webpack-internal:///./node_modules/next/dist/compiled/#next/react-dev-overlay/dist/client.js:301:63)
at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/compiled/#next/react-dev-overlay/dist/client.js:850:919)
at Container (webpack-internal:///./node_modules/next/dist/client/index.js:62:1)
at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:172:11)
at Root (webpack-internal:///./node_modules/next/dist/client/index.js:347:11)
This is my code from nextjs13.1. Please help me. How should I add key to this writing format:
import styles from "./styles.module.scss";
import Link from "next/link";
export default function Links() {
return (
<div className={styles.footer_links}>
{
links.map((link, i) =>(
<ul>
{
i ===0 ? (
<img src="../images/logo.png" alt="" />
) : (
<b>{link.heading}</b>
)}
{
link.links.map((link) =>(
<li>
<Link href={link.link}>{link.name}</Link>
</li>
))
}
</ul>
))
}
</div>
);
}
const links = [
{
heading: "SHOPPAY",
links: [
{
id: 1,
name: "About us",
link: "/about",
},
{
name: "Contact us",
link: "",
},
{
name: "Social Responsibility",
link: "",
},
],
},
{
heading: "HELP & SUPPORT",
links: [
{
name: "Shipping Info",
link: "",
},
{
name: "Returns",
link: "",
},
{
name: "How To Order",
link: "",
},
{
name: "How To Track",
link: "",
},
{
name: "Size Guide",
link: "",
},
],
},
{
heading: "CUSTOMER SERVICE",
links: [
{
name: "Customer service",
link: "",
},
{
name: "Terms and Conditions",
link: "",
},
{
name: "Consumers(Transactions)",
link: "",
},
{
name: "Take our feedback survey",
link: "",
},
],
},
];
React requires every element in a loop like map to have a key prop with a unique value, like an ID. In your case, both map functions need to define a key on the returned parent element.
If your ID keys are incremented numbers, they should also be avoided since these IDs are not globally unique.
Typically the index i shouldn't be used for the key, but in your case, another unique string isn't defined for every item.
links.map((link, i) =>(
<ul key={`link-${i}`}>
{link.links.map((link, i) =>(
<li key={`sublink-${i}`}>...</li>
))}
</ul>
))
A best-case scenario is that you globally unique IDs defined for each link, and the ID is used as the keys.
links.map((link) =>(
<ul key={link.id}>
{link.links.map((link) =>(
<li key={link.id}>...</li>
))}
</ul>
))
I'm very new to Vue syntax, so please forgive me (and feel free to correct!) my terminology and assumptions. In short, I have a very simple goal, to get values from an object where currently I am getting key names.
In the code I am trying to modify, there is a Vue object called "tags," part of a complete "video" object (returned from Vimeo), that, when bound in a Vue "x-template" script to html - like so:
<figure class="vimeography-thumbnail" :class="video.tags" >
...produces output like this:
<figure data-v-de73d604 data-v-5a40afb8 class="vimeography-thumbnail name canonical name canonical name canonical" index="18">
The output we need instead would look more like this:
<figure data-v-de73d604 data-v-5a40afb8 class="vimeography-thumbnail hands feet eyes" index="18">
In other words, "hands," "feet," and "eyes" would be the values of "canonical" for the set of three "tags." The "data" and "index" elements being output are, I believe, irrelevant.
I got as far as I did through some investigatory hacking around, and, though the result is wrong, I can see from page source that "name" and "canonical" are the correct key names, that the values I need are also present, and that the number of pairs of keys for each video thumbnail is as would be expected given each specific Vimeo video's number of tags.
I do see a lot of discussion about iterating over the object (or is it really an array?), but the :class shorthand seems already to be doing that, so I wonder if there isn't a simple shorthand way to get the values instead of keys. I tried video.tags.values and video.tags[canonical]just for the heck of it, but no luck.
Just to provide a larger context, the script is a template customization script for a WordPress plugin - Vimeography - that has already done the job of constructing the needed variables from the Vimeo API.
The larger template - for modifying gallery thumbnails - looks like this:
<script type="text/x-template" id="vimeography-timber-thumbnail">
<figure class="vimeography-thumbnail" :class="video.tags" >
<img class="vimeography-thumbnail-img" :src="thumbnailUrl" :alt="video.name" />
<figcaption>
<h2 class="vimeography-title">{{video.name}}</h2>
<div class="vimeography-description" v-html="video.description"></div><!-- try two -->
<router-link class="vimeography-link" :to="this.query" :title="video.name" exact exact-active-class="vimeography-link-active">View more </router-link>
</figcaption>
</figure>
</script>
A typical tags object looks like this in page source:
"tags":[{"name":"neck massage","canonical":"neckmassage"},{"name":"release","canonical":"release"},{"name":"shoulder pain","canonical":"shoulderpain"}]
So, as you can see if you return to the output example above, I'm getting the first and second key names "name" and "canonical" in sequence, separated by spaces, when what I need is each second key value.
On request - a video object - the "tags" appear around midway in it.
"466907727":{"uri":"\/videos\/466907727","name":"Headache Relief w\/ Ruth","description":"Give yourself some time with this one. If you feel a headache coming on or you can't get rid of one, try out these techniques to release face, jaw, and ear muscles that tense up throughout the day.","link":"https:\/\/vimeo.com\/466907727","duration":"11:43","width":1280,"height":720,"embed":{"buttons":{"like":true,"watchlater":true,"share":true,"embed":false,"hd":false,"fullscreen":true,"scaling":true},"logos":{"vimeo":false,"custom":{"active":true,"url":"https:\/\/i.vimeocdn.com\/player\/415649.png?mw=100&mh=100","link":"https:\/\/bodyworksdw.com","sticky":true}},"title":{"name":"show","owner":"show","portrait":"hide"},"playbar":true,"volume":true,"speed":false,"color":"ffffff","uri":"\/presets\/120692845","html":"<iframe src=\"https:\/\/player.vimeo.com\/video\/466907727?title=0&byline=0&portrait=0&speed=0&badge=0&autopause=0&player_id=0&app_id=27459\" width=\"1280\" height=\"720\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture\" allowfullscreen title=\"Headache Relief w\/ Ruth\"><\/iframe>","badges":{"hdr":false,"live":{"streaming":false,"archived":false},"staff_pick":{"normal":false,"best_of_the_month":false,"best_of_the_year":false,"premiere":false},"vod":false,"weekend_challenge":false}},"created_time":"2020-10-10T17:17:42+00:00","privacy":{"view":"disable"},"pictures":{"uri":"\/videos\/466907727\/pictures\/972886256","active":true,"type":"custom","sizes":[{"width":100,"height":75,"link":"https:\/\/i.vimeocdn.com\/video\/972886256_100x75?r=pad","link_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_100x75&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png"},{"width":200,"height":150,"link":"https:\/\/i.vimeocdn.com\/video\/972886256_200x150?r=pad","link_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_200x150&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png"},{"width":295,"height":166,"link":"https:\/\/i.vimeocdn.com\/video\/972886256_295x166?r=pad","link_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_295x166&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png"},{"width":640,"height":360,"link":"https:\/\/i.vimeocdn.com\/video\/972886256_640x360?r=pad","link_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_640x360&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png"},{"width":1280,"height":720,"link":"https:\/\/i.vimeocdn.com\/video\/972886256_1280x720?r=pad","link_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1280x720&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png"},{"width":1280,"height":720,"link":"https:\/\/i.vimeocdn.com\/video\/972886256_1280x720?r=pad","link_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1280x720&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png"},{"width":1280,"height":720,"link":"https:\/\/i.vimeocdn.com\/video\/972886256_1280x720?r=pad","link_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1280x720&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png"},{"width":1280,"height":720,"link":"https:\/\/i.vimeocdn.com\/video\/972886256_1280x720?r=pad","link_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1280x720&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png"},{"width":1920,"height":1080,"link":"https:\/\/i.vimeocdn.com\/video\/972886256_1920x1080?r=pad","link_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1920x1080&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png"}],"resource_key":"0e08692aa74f2e89587bd88aedf898a1faa1ccb9","default_picture":false},"tags":[{"name":"Jaw","canonical":"jaw"},{"name":"Head","canonical":"head"},{"name":"Recover","canonical":"recover"}],"stats":{"plays":3},"metadata":{"connections":{"texttracks":{"uri":"\/videos\/466907727\/texttracks","options":["GET","POST"],"total":0}}},"user":{"account":"business"},"download":[{"quality":"sd","type":"video\/mp4","width":426,"height":240,"expires":"2021-05-16T10:05:23+00:00","link":"https:\/\/player.vimeo.com\/play\/2073102730?s=466907727_1621159523_101bba513873dd67b93c563f09e28890&loc=external&context=Vimeo%5CController%5CApi%5CResources%5CUser%5CAlbum%5CVideosController.&download=1&filename=Headache%2BRelief%2Bw%252F%2BRuth139.mp4","created_time":"2020-10-10T17:19:59+00:00","fps":29.97,"size":32299937,"md5":"fcad390159d07049c597c47dd7edc921","public_name":"SD 240p","size_short":"30.8MB"},{"quality":"sd","type":"video\/mp4","width":960,"height":540,"expires":"2021-05-16T10:05:23+00:00","link":"https:\/\/player.vimeo.com\/play\/2073102727?s=466907727_1621159523_03598ebe80a895414613bd3cef32af54&loc=external&context=Vimeo%5CController%5CApi%5CResources%5CUser%5CAlbum%5CVideosController.&download=1&filename=Headache%2BRelief%2Bw%252F%2BRuth165.mp4","created_time":"2020-10-10T17:19:59+00:00","fps":29.97,"size":143540809,"md5":"553cd5d74d4ab59cc16547b486c82a30","public_name":"SD 540p","size_short":"136.89MB"},{"quality":"sd","type":"video\/mp4","width":640,"height":360,"expires":"2021-05-16T10:05:23+00:00","link":"https:\/\/player.vimeo.com\/play\/2073102718?s=466907727_1621159523_613694ef950f06a2a4a06376d9c03708&loc=external&context=Vimeo%5CController%5CApi%5CResources%5CUser%5CAlbum%5CVideosController.&download=1&filename=Headache%2BRelief%2Bw%252F%2BRuth164.mp4","created_time":"2020-10-10T17:19:59+00:00","fps":29.97,"size":56848778,"md5":"282afb947f67e072bfb44b84557ff231","public_name":"SD 360p","size_short":"54.22MB"},{"quality":"hd","type":"video\/mp4","width":1280,"height":720,"expires":"2021-05-16T10:05:23+00:00","link":"https:\/\/player.vimeo.com\/play\/2073102708?s=466907727_1621159523_0d0c2d785bc32949b4eca945a220741a&loc=external&context=Vimeo%5CController%5CApi%5CResources%5CUser%5CAlbum%5CVideosController.&download=1&filename=Headache%2BRelief%2Bw%252F%2BRuth174.mp4","created_time":"2020-10-10T17:19:59+00:00","fps":29.97,"size":244431967,"md5":"8db87793d97332351b77aba3d1e5a042","public_name":"HD 720p","size_short":"233.11MB"}],"status":"available","video_id":"466907727","id":466907727,"human_created_time":"October 10, 2020","thumbnail_tiny":"https:\/\/i.vimeocdn.com\/video\/972886256_295x166?r=pad","thumbnail_tiny_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_295x166&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png","thumbnail_small":"https:\/\/i.vimeocdn.com\/video\/972886256_640x360?r=pad","thumbnail_small_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_640x360&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png","thumbnail_medium":"https:\/\/i.vimeocdn.com\/video\/972886256_1280x720?r=pad","thumbnail_medium_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1280x720&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png","thumbnail_large":"https:\/\/i.vimeocdn.com\/video\/972886256_1280x720?r=pad","thumbnail_large_with_play_button":"https:\/\/i.vimeocdn.com\/filter\/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1280x720&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png"},
A simple inlined method within your script template tag should suffice:
:class="
video.tags.reduce((classes, obj) => {
classes.push(obj.canonical)
return classes
}, [])
"
This should be sufficient enough to reduce down the existing array of objects into a simple array of string values.
As for why this happens - in the object syntax for classes, vue looks at the left hand assignment and will apply it if the right hand assignment is truthy. in your case, the indices are applied because the values of them are strings, which are truthy.
couldn't get your problem exactly, if you want to print the value call it by its property name ".name" as you did, but you have to be sure that video is a single object.
<figure
v-for="(item, index) in tags"
:v-key="index"
data-v-de73d604
data-v-5a40afb8
:class="item.name + item.canonical"
class="vimeography-thumbnail"
:index="18 + index"
></figure>
with tags array
<template>
<div id="app">
<!-- ..-->
<figure
v-for="(item, index) in tags"
:v-key="index"
data-v-de73d604
data-v-5a40afb8
:class="item.name + ' ' + item.canonical"
class="vimeography-thumbnail"
:index="18 + index"
></figure>
<!-- ..-->
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld";
export default {
data() {
return {
tags: [
{ name: "neck massage", canonical: "neckmassage" },
{ name: "release", canonical: "release" },
{ name: "shoulder pain", canonical: "shoulderpain" },
],
};
},
};
</script>
//new Update
<template>
<div id="app">
{{ video.tags }}
<figure
v-for="(item, index) in video.tags"
:v-key="index"
data-v-de73d604
data-v-5a40afb8
:class="item.name + ' ' + item.canonical"
class="vimeography-thumbnail"
:index="18 + index"
></figure>
</div>
</template>
<script>
export default {
mounted(){
var get = {
466907727: {
uri: "/videos/466907727",
name: "Headache Relief w/ Ruth",
description:
"Give yourself some time with this one. If you feel a headache coming on or you can't get rid of one, try out these techniques to release face, jaw, and ear muscles that tense up throughout the day.",
link: "https://vimeo.com/466907727",
duration: "11:43",
width: 1280,
height: 720,
embed: {
buttons: {
like: true,
watchlater: true,
share: true,
embed: false,
hd: false,
fullscreen: true,
scaling: true,
},
logos: {
vimeo: false,
custom: {
active: true,
url: "https://i.vimeocdn.com/player/415649.png?mw=100&mh=100",
link: "https://bodyworksdw.com",
sticky: true,
},
},
title: { name: "show", owner: "show", portrait: "hide" },
playbar: true,
volume: true,
speed: false,
color: "ffffff",
uri: "/presets/120692845",
html:
'<iframe src="https://player.vimeo.com/video/466907727?title=0&byline=0&portrait=0&speed=0&badge=0&autopause=0&player_id=0&app_id=27459" width="1280" height="720" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen title="Headache Relief w/ Ruth"></iframe>',
badges: {
hdr: false,
live: { streaming: false, archived: false },
staff_pick: {
normal: false,
best_of_the_month: false,
best_of_the_year: false,
premiere: false,
},
vod: false,
weekend_challenge: false,
},
},
created_time: "2020-10-10T17:17:42+00:00",
privacy: { view: "disable" },
pictures: {
uri: "/videos/466907727/pictures/972886256",
active: true,
type: "custom",
sizes: [
{
width: 100,
height: 75,
link: "https://i.vimeocdn.com/video/972886256_100x75?r=pad",
link_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_100x75&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
},
{
width: 200,
height: 150,
link: "https://i.vimeocdn.com/video/972886256_200x150?r=pad",
link_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_200x150&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
},
{
width: 295,
height: 166,
link: "https://i.vimeocdn.com/video/972886256_295x166?r=pad",
link_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_295x166&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
},
{
width: 640,
height: 360,
link: "https://i.vimeocdn.com/video/972886256_640x360?r=pad",
link_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_640x360&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
},
{
width: 1280,
height: 720,
link: "https://i.vimeocdn.com/video/972886256_1280x720?r=pad",
link_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1280x720&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
},
{
width: 1280,
height: 720,
link: "https://i.vimeocdn.com/video/972886256_1280x720?r=pad",
link_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1280x720&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
},
{
width: 1280,
height: 720,
link: "https://i.vimeocdn.com/video/972886256_1280x720?r=pad",
link_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1280x720&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
},
{
width: 1280,
height: 720,
link: "https://i.vimeocdn.com/video/972886256_1280x720?r=pad",
link_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1280x720&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
},
{
width: 1920,
height: 1080,
link: "https://i.vimeocdn.com/video/972886256_1920x1080?r=pad",
link_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1920x1080&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
},
],
resource_key: "0e08692aa74f2e89587bd88aedf898a1faa1ccb9",
default_picture: false,
},
tags: [
{ name: "Jaw", canonical: "jaw" },
{ name: "Head", canonical: "head" },
{ name: "Recover", canonical: "recover" },
],
stats: { plays: 3 },
metadata: {
connections: {
texttracks: {
uri: "/videos/466907727/texttracks",
options: ["GET", "POST"],
total: 0,
},
},
},
user: { account: "business" },
download: [
{
quality: "sd",
type: "video/mp4",
width: 426,
height: 240,
expires: "2021-05-16T10:05:23+00:00",
link:
"https://player.vimeo.com/play/2073102730?s=466907727_1621159523_101bba513873dd67b93c563f09e28890&loc=external&context=Vimeo%5CController%5CApi%5CResources%5CUser%5CAlbum%5CVideosController.&download=1&filename=Headache%2BRelief%2Bw%252F%2BRuth139.mp4",
created_time: "2020-10-10T17:19:59+00:00",
fps: 29.97,
size: 32299937,
md5: "fcad390159d07049c597c47dd7edc921",
public_name: "SD 240p",
size_short: "30.8MB",
},
{
quality: "sd",
type: "video/mp4",
width: 960,
height: 540,
expires: "2021-05-16T10:05:23+00:00",
link:
"https://player.vimeo.com/play/2073102727?s=466907727_1621159523_03598ebe80a895414613bd3cef32af54&loc=external&context=Vimeo%5CController%5CApi%5CResources%5CUser%5CAlbum%5CVideosController.&download=1&filename=Headache%2BRelief%2Bw%252F%2BRuth165.mp4",
created_time: "2020-10-10T17:19:59+00:00",
fps: 29.97,
size: 143540809,
md5: "553cd5d74d4ab59cc16547b486c82a30",
public_name: "SD 540p",
size_short: "136.89MB",
},
{
quality: "sd",
type: "video/mp4",
width: 640,
height: 360,
expires: "2021-05-16T10:05:23+00:00",
link:
"https://player.vimeo.com/play/2073102718?s=466907727_1621159523_613694ef950f06a2a4a06376d9c03708&loc=external&context=Vimeo%5CController%5CApi%5CResources%5CUser%5CAlbum%5CVideosController.&download=1&filename=Headache%2BRelief%2Bw%252F%2BRuth164.mp4",
created_time: "2020-10-10T17:19:59+00:00",
fps: 29.97,
size: 56848778,
md5: "282afb947f67e072bfb44b84557ff231",
public_name: "SD 360p",
size_short: "54.22MB",
},
{
quality: "hd",
type: "video/mp4",
width: 1280,
height: 720,
expires: "2021-05-16T10:05:23+00:00",
link:
"https://player.vimeo.com/play/2073102708?s=466907727_1621159523_0d0c2d785bc32949b4eca945a220741a&loc=external&context=Vimeo%5CController%5CApi%5CResources%5CUser%5CAlbum%5CVideosController.&download=1&filename=Headache%2BRelief%2Bw%252F%2BRuth174.mp4",
created_time: "2020-10-10T17:19:59+00:00",
fps: 29.97,
size: 244431967,
md5: "8db87793d97332351b77aba3d1e5a042",
public_name: "HD 720p",
size_short: "233.11MB",
},
],
status: "available",
video_id: "466907727",
id: 466907727,
human_created_time: "October 10, 2020",
thumbnail_tiny: "https://i.vimeocdn.com/video/972886256_295x166?r=pad",
thumbnail_tiny_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_295x166&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
thumbnail_small: "https://i.vimeocdn.com/video/972886256_640x360?r=pad",
thumbnail_small_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_640x360&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
thumbnail_medium:
"https://i.vimeocdn.com/video/972886256_1280x720?r=pad",
thumbnail_medium_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1280x720&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
thumbnail_large:
"https://i.vimeocdn.com/video/972886256_1280x720?r=pad",
thumbnail_large_with_play_button:
"https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F972886256_1280x720&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png",
},
};
// here we check if the getting data is array or object and make it okay to video object.
get == Array.isArray()
? (this.video = get[0])
: (this.video = get[Object.keys(get)]);
},
data(){
return{
video:{
}
}
}
}
</script>
Why in component
var matrix = new enyo.Control({
name:"Matrix",
tag: "div",
classes : 'strategies',
/*handlers: {
init: "initHandler"
},*/
components: [
{ tag: "div", classes: "blankblock", content: ' ' },
{ tag: "div", classes: "label1", content: 'Player A' },
{ tag: "div", classes: "label2", content: 'B' },
{ name:'matrixTable', tag: "table", components: [
{ name: 'tr1', tag: 'tr', components: [
{ tag: 'td', components: [{tag: 'input'}]},
{ tag: 'td', components: [{tag: 'input'}]}
]},
{tag: 'tr', components: [
{tag: 'td', components: [{tag: 'input'}]},
{tag: 'td', components: [{tag: 'input'}]}
]}
]} ,
{ name: 'addV', tag: "button", classes:'addV', content: "+", ontap: "addRow" },
{ name: 'addH', tag: "button", classes:'addH', content: "+", ontap: "addColl" }
],
addRow: function(inSource, inEvent){
this.$.matrixTable.createComponent
alert(this.$.matrixTable.$.toSource());
},
addColl: function(inSource, inEvent){
}
});
this.$ include all components, even those with nesting order 2
I expect
this.$.matrixTable.$.tr1
but I have
this.$.tr1
Because you declared them as part of the Matrix kind then Enyo will have them all owned by the Matrix kind. If you want them to be owned as you described then you need to break out the MatrixTable kind into its own separate kind. If you want to enforce that encapsulation then you need to create a kind to hide it.
Further, you should always avoid going two levels deep into a kind. In other words, this.$.matrixTable.$.tr1 would be bad form. Make properties or add functions to return values.
In enyo you need to be aware of two chains: owner chain vs parent-child chain.
Whereas "matrixTable" is a parent of "tr1", an owner of "tr1" is "Matrix".
So to get to "tr1" from "Matrix", you can go two ways:
this.$.tr1 or this.children[3].children[0],
similarly, to get to "Matrix" from "tr1" you can do:
this.$.tr1.owner or this.$.tr1.parent.parent
This way, no matter how deeply nested are your components, the owner will always be the kind within which the component is defined.
I have a page with 3 tabs(dijit.layout.TabContainer) and each tab as 2-3 accordians(dijit.layout.AccordionContainer). From a single data store, I am trying to display different grids in each of the accordians.
I am able to display data in a single accordian, but the other grids show up blank, I cant even see headers. If I try to display multiple grids outside the tabs/accordians, it works fine. Not sure what is it that I am missing here.
var jsonStore = new dojo.data.ItemFileWriteStore({ data:{
"identifier": "rowIdentifier",
"label": "gridIdentifier",
"items": [
{
"rowIdentifier": 123,
"gridIdentifier": "labor",
"description": "Project Manager",
"hours": 100.0,
"rate": 100.0
},
{
"rowIdentifier": 234,
"gridIdentifier": "oem",
"description": "Developer",
"hours": 100.0,
"rate": 100.0
}
]
} });
var grid1 = null;
var grid2 = null;
var grid1Layout= [
{ field: "rowIdentifier", width: "auto", name: "Row Identifier",hidden:true },
{ field: "gridIdentifier", width: "auto", name: "Grid Identifier",hidden:true },
{ field: "description", width: "auto", name: "Tier/Description", editable:true },
{ field: "hours", width: "auto", name: "Hours" },
{ field: "rate", width: "auto", name: "Rate <br/>" }
];
grid1 = new dojox.grid.DataGrid({
query: { gridIdentifier: 'labor' },
store: jsonStore,
singleClickEdit: true,
structure: grid1Layout,
rowsPerPage: 6
}, 'grid1Node');
var grid2Layout= [
{ field: "rowIdentifier", width: "auto", name: "Row Identifier",hidden:true },
{ field: "gridIdentifier", width: "auto", name: "Grid Identifier",hidden:true },
{ field: "description", width: "auto", name: "Tier/Description", editable:true },
{ field: "hours", width: "auto", name: "Hours" },
{ field: "rate", width: "auto", name: "Rate <br/>" }
];
grid2 = new dojox.grid.DataGrid({
query: { gridIdentifier: 'oem' },
store: jsonStore,
singleClickEdit: true,
structure: grid2Layout,
rowsPerPage: 6
}, 'grid2Node');
// Call startup, in order to render the grid:
grid1.startup();
grid2.startup();
Below is my HTML
<div style="height: 105px;">
<div dojoType="dijit.layout.TabContainer" style="width: 100%;"
doLayout="false">
<div dojoType="dijit.layout.ContentPane" title="Labor" selected="true">
<div id="LaborAccordian" style="width:auto; height: 300px">
<div dojoType="dijit.layout.AccordionContainer" style="height: 300px;">
<div dojoType="dijit.layout.ContentPane" title="Tab1 Acc1" selected="true">
<div id="grid1Node"></div></div>
<div dojoType="dijit.layout.ContentPane" title="Tab1 Acc2"><div id="SubContractorLaborGridNode"></div></div>
<div dojoType="dijit.layout.ContentPane" title="Tab1 Acc3"><div id="VendedLaborGridNode"></div></div>
</div>
</div>
</div>
<div dojoType="dijit.layout.ContentPane" title="OEM products">
<div id="OEMAccordian" style="width:auto; height: 300px">
<div dojoType="dijit.layout.AccordionContainer" style="height: 300px;">
<div dojoType="dijit.layout.ContentPane" title="Tab2 Acc1"><div id="grid2Node"></div></div>
<div dojoType="dijit.layout.ContentPane" title="Tab2 Acc2" selected="true"></div>
</div>
</div>
</div>
</div>
<!-- end of the div -->
</div>
I have all the appropriate DOJO.requires() in the . Please let me know what I am missing to display the same data store, in different flavors in different accordian containers?
Thanks
SK
From your description, most likely the grid is created successfully, but doesn't show up because the dimension is 0 * 0. The could happen because when the grid is created in a hidden accordion pane, the size of the grid's containing DOM node is actually zero. So when the hidden accordion pane is made visible, the grid size is still zero. This also could happen due to dynamic height and width are specified in the grid's containing node using CSS, e.g. using height or width like 100%. Dynamic height or width may cause problem when calculating the actual height and width.
So my suggestion is to first check the DOM structure using Firebug to see whether the grid is created or not. Most likely you'll see the grid's DOM structure but it doesn't show up because the size is 0 * 0. You can use Firebug to verify it. If this is the case, you can manually instruct the grid to re-calculate its size again by using the resize function. You can use dojo.connect to connect to dijit.layout.AccordionPane's onSelected function and invoke the grid's resize function. Then when a accordion page is selected, the grid inside of it is automatically resized.
I think what Alex Cheng said is correct. And the following changes may slove the problem.
<div id="grid1Node" style="height:100%"></div>
<div id="grid2Node" style="height:100%"></div>
Applying heights for the container of the Grid dom node.
Another solution is to use absolute (not dynamic) height settings, eg:
<div id="grid1Node" style="height:100px"></div>
<div id="grid2Node" style="height:100px"></div>